scene-capability-engine 3.0.2 → 3.0.4
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 +2 -0
- package/docs/command-reference.md +31 -6
- package/docs/images/wechat-qr.png +0 -0
- package/docs/moqui-capability-matrix.md +21 -0
- package/docs/moqui-template-core-library-playbook.md +31 -1
- package/lib/commands/auto.js +1155 -14
- package/lib/commands/scene.js +1 -1
- package/lib/data/moqui-capability-lexicon.json +263 -4
- package/lib/orchestrator/orchestration-engine.js +55 -6
- package/package.json +1 -1
package/lib/commands/auto.js
CHANGED
|
@@ -1538,6 +1538,8 @@ function registerAutoCommands(program) {
|
|
|
1538
1538
|
.option('--min-capability-semantic <n>', 'Minimum Moqui capability semantic completeness percent (default: 100)', parseFloat)
|
|
1539
1539
|
.option('--require-capability-semantic', 'Require capability semantic completeness gate (default: enabled)')
|
|
1540
1540
|
.option('--no-require-capability-semantic', 'Disable capability semantic completeness gate (not recommended)')
|
|
1541
|
+
.option('--require-capability-lexicon', 'Require capability lexicon normalization gate (default: enabled)')
|
|
1542
|
+
.option('--no-require-capability-lexicon', 'Disable capability lexicon normalization gate (not recommended)')
|
|
1541
1543
|
.option('--format <type>', 'Matrix report format: json|markdown (default: json)', 'json')
|
|
1542
1544
|
.option('--out <path>', 'Write matrix report output file')
|
|
1543
1545
|
.option('--remediation-queue-out <path>', `Write remediation queue lines (default: ${AUTO_HANDOFF_MOQUI_REMEDIATION_QUEUE_FILE})`, AUTO_HANDOFF_MOQUI_REMEDIATION_QUEUE_FILE)
|
|
@@ -1586,6 +1588,9 @@ function registerAutoCommands(program) {
|
|
|
1586
1588
|
if (result.gates && result.gates.capability_semantic) {
|
|
1587
1589
|
console.log(chalk.gray(` Semantic gate: ${result.gates.capability_semantic.passed ? 'pass' : 'fail'}`));
|
|
1588
1590
|
}
|
|
1591
|
+
if (result.gates && result.gates.capability_lexicon) {
|
|
1592
|
+
console.log(chalk.gray(` Lexicon gate: ${result.gates.capability_lexicon.passed ? 'pass' : 'fail'}`));
|
|
1593
|
+
}
|
|
1589
1594
|
if (result.remediation_queue && result.remediation_queue.file) {
|
|
1590
1595
|
console.log(chalk.gray(` Remediation queue: ${result.remediation_queue.file} (${result.remediation_queue.goal_count})`));
|
|
1591
1596
|
}
|
|
@@ -1748,6 +1753,15 @@ function registerAutoCommands(program) {
|
|
|
1748
1753
|
? `${moquiSummary.valid_rate_percent}%`
|
|
1749
1754
|
: 'n/a';
|
|
1750
1755
|
console.log(chalk.gray(` Portfolio: ${moquiSummary.portfolio_passed === true ? 'pass' : 'fail'} | avg=${scoreText} | valid-rate=${validRateText}`));
|
|
1756
|
+
const entityRateText = formatAutoHandoffMoquiCoverageMetric(moquiSummary, 'entity_coverage', 'rate_percent', '%');
|
|
1757
|
+
const ruleClosedRateText = formatAutoHandoffMoquiCoverageMetric(moquiSummary, 'business_rule_closed', 'rate_percent', '%');
|
|
1758
|
+
const decisionClosedRateText = formatAutoHandoffMoquiCoverageMetric(moquiSummary, 'decision_closed', 'rate_percent', '%');
|
|
1759
|
+
console.log(chalk.gray(` Coverage: entity=${entityRateText} | rule-closed=${ruleClosedRateText} | decision-closed=${decisionClosedRateText}`));
|
|
1760
|
+
const regressionText = formatAutoHandoffMoquiCoverageRegressions(
|
|
1761
|
+
moquiBaseline && moquiBaseline.compare ? moquiBaseline.compare : {},
|
|
1762
|
+
3
|
|
1763
|
+
);
|
|
1764
|
+
console.log(chalk.gray(` Regressions: ${regressionText}`));
|
|
1751
1765
|
}
|
|
1752
1766
|
}
|
|
1753
1767
|
if (result.current_overview && result.current_overview.scene_package_batch) {
|
|
@@ -1883,11 +1897,14 @@ function registerAutoCommands(program) {
|
|
|
1883
1897
|
.option('--no-require-ontology-validation', 'Gate: disable manifest ontology_validation requirement (not recommended)')
|
|
1884
1898
|
.option('--require-moqui-baseline', 'Gate: require Moqui baseline portfolio to pass (default: enabled)')
|
|
1885
1899
|
.option('--no-require-moqui-baseline', 'Gate: disable Moqui baseline portfolio requirement (not recommended)')
|
|
1900
|
+
.option('--max-moqui-matrix-regressions <n>', 'Gate: maximum allowed Moqui matrix regression signals (default: 0)', parseInt)
|
|
1886
1901
|
.option('--require-scene-package-batch', 'Gate: require scene package publish-batch dry-run gate to pass when applicable (default: enabled)')
|
|
1887
1902
|
.option('--no-require-scene-package-batch', 'Gate: disable scene package publish-batch dry-run requirement (not recommended)')
|
|
1888
1903
|
.option('--min-capability-coverage <n>', 'Gate: minimum Moqui capability coverage percent (default: 100)', parseFloat)
|
|
1889
1904
|
.option('--require-capability-coverage', 'Gate: require capability coverage threshold when capabilities are declared (default: enabled)')
|
|
1890
1905
|
.option('--no-require-capability-coverage', 'Gate: disable capability coverage requirement (not recommended)')
|
|
1906
|
+
.option('--require-capability-lexicon', 'Gate: require capability lexicon normalization (unknown expected/provided aliases not allowed, default: enabled)')
|
|
1907
|
+
.option('--no-require-capability-lexicon', 'Gate: disable capability lexicon normalization requirement (not recommended)')
|
|
1891
1908
|
.option('--require-release-gate-preflight', 'Gate: require release-gate preflight signal to be available and unblocked (default: disabled/advisory)')
|
|
1892
1909
|
.option('--no-require-release-gate-preflight', 'Gate: disable release-gate preflight hard requirement (default)')
|
|
1893
1910
|
.option('--release-evidence-window <n>', 'Release evidence trend window size (2-50, default: 5)', parseInt)
|
|
@@ -1939,6 +1956,15 @@ function registerAutoCommands(program) {
|
|
|
1939
1956
|
? `${baselineSummary.valid_rate_percent}%`
|
|
1940
1957
|
: 'n/a';
|
|
1941
1958
|
console.log(chalk.gray(` Portfolio: ${baselineSummary.portfolio_passed ? 'pass' : 'fail'} | avg=${scoreText} | valid-rate=${validRateText}`));
|
|
1959
|
+
const entityRateText = formatAutoHandoffMoquiCoverageMetric(baselineSummary, 'entity_coverage', 'rate_percent', '%');
|
|
1960
|
+
const ruleClosedRateText = formatAutoHandoffMoquiCoverageMetric(baselineSummary, 'business_rule_closed', 'rate_percent', '%');
|
|
1961
|
+
const decisionClosedRateText = formatAutoHandoffMoquiCoverageMetric(baselineSummary, 'decision_closed', 'rate_percent', '%');
|
|
1962
|
+
console.log(chalk.gray(` Coverage: entity=${entityRateText} | rule-closed=${ruleClosedRateText} | decision-closed=${decisionClosedRateText}`));
|
|
1963
|
+
const regressionText = formatAutoHandoffMoquiCoverageRegressions(
|
|
1964
|
+
result.moqui_baseline && result.moqui_baseline.compare ? result.moqui_baseline.compare : {},
|
|
1965
|
+
3
|
|
1966
|
+
);
|
|
1967
|
+
console.log(chalk.gray(` Regressions: ${regressionText}`));
|
|
1942
1968
|
}
|
|
1943
1969
|
if (result.moqui_baseline.output && result.moqui_baseline.output.json) {
|
|
1944
1970
|
console.log(chalk.gray(` Baseline report: ${result.moqui_baseline.output.json}`));
|
|
@@ -8096,6 +8122,13 @@ function buildAutoHandoffRegressionSnapshot(report) {
|
|
|
8096
8122
|
? scenePackageBatch.status
|
|
8097
8123
|
: gateActual.scene_package_batch_status
|
|
8098
8124
|
);
|
|
8125
|
+
const moquiBaseline = payload && payload.moqui_baseline ? payload.moqui_baseline : {};
|
|
8126
|
+
const moquiCompare = moquiBaseline && moquiBaseline.compare ? moquiBaseline.compare : {};
|
|
8127
|
+
const moquiMatrixRegressionCount = Number(
|
|
8128
|
+
gateActual.moqui_matrix_regression_count !== undefined
|
|
8129
|
+
? gateActual.moqui_matrix_regression_count
|
|
8130
|
+
: buildAutoHandoffMoquiCoverageRegressions(moquiCompare).length
|
|
8131
|
+
);
|
|
8099
8132
|
let sceneBatchPassed = null;
|
|
8100
8133
|
if (sceneBatchStatus && sceneBatchStatus !== 'skipped') {
|
|
8101
8134
|
sceneBatchPassed = sceneBatchStatus === 'passed';
|
|
@@ -8119,6 +8152,7 @@ function buildAutoHandoffRegressionSnapshot(report) {
|
|
|
8119
8152
|
ontology_undecided_decisions: Number.isFinite(ontologyUndecidedDecisions) ? ontologyUndecidedDecisions : null,
|
|
8120
8153
|
ontology_business_rule_pass_rate_percent: Number.isFinite(businessRulePassRate) ? businessRulePassRate : null,
|
|
8121
8154
|
ontology_decision_resolved_rate_percent: Number.isFinite(decisionResolvedRate) ? decisionResolvedRate : null,
|
|
8155
|
+
moqui_matrix_regression_count: Number.isFinite(moquiMatrixRegressionCount) ? moquiMatrixRegressionCount : null,
|
|
8122
8156
|
scene_package_batch_status: sceneBatchStatus || null,
|
|
8123
8157
|
scene_package_batch_passed: typeof sceneBatchPassed === 'boolean' ? sceneBatchPassed : null,
|
|
8124
8158
|
scene_package_batch_failure_count: Number.isFinite(sceneBatchFailureCount) ? sceneBatchFailureCount : null,
|
|
@@ -8193,6 +8227,12 @@ function buildAutoHandoffRegressionComparison(currentSnapshot, previousSnapshot)
|
|
|
8193
8227
|
)
|
|
8194
8228
|
? currentSnapshot.scene_package_batch_failure_count - previousSnapshot.scene_package_batch_failure_count
|
|
8195
8229
|
: null;
|
|
8230
|
+
const deltaMoquiMatrixRegressionCount = (
|
|
8231
|
+
Number.isFinite(currentSnapshot.moqui_matrix_regression_count) &&
|
|
8232
|
+
Number.isFinite(previousSnapshot.moqui_matrix_regression_count)
|
|
8233
|
+
)
|
|
8234
|
+
? currentSnapshot.moqui_matrix_regression_count - previousSnapshot.moqui_matrix_regression_count
|
|
8235
|
+
: null;
|
|
8196
8236
|
|
|
8197
8237
|
let trend = 'stable';
|
|
8198
8238
|
if (
|
|
@@ -8212,7 +8252,8 @@ function buildAutoHandoffRegressionComparison(currentSnapshot, previousSnapshot)
|
|
|
8212
8252
|
(deltaOntologyQualityScore !== null && deltaOntologyQualityScore < 0) ||
|
|
8213
8253
|
(deltaOntologyUnmappedRules !== null && deltaOntologyUnmappedRules > 0) ||
|
|
8214
8254
|
(deltaOntologyUndecidedDecisions !== null && deltaOntologyUndecidedDecisions > 0) ||
|
|
8215
|
-
(deltaSceneBatchFailureCount !== null && deltaSceneBatchFailureCount > 0)
|
|
8255
|
+
(deltaSceneBatchFailureCount !== null && deltaSceneBatchFailureCount > 0) ||
|
|
8256
|
+
(deltaMoquiMatrixRegressionCount !== null && deltaMoquiMatrixRegressionCount > 0)
|
|
8216
8257
|
) {
|
|
8217
8258
|
trend = 'degraded';
|
|
8218
8259
|
}
|
|
@@ -8229,6 +8270,7 @@ function buildAutoHandoffRegressionComparison(currentSnapshot, previousSnapshot)
|
|
|
8229
8270
|
ontology_undecided_decisions: deltaOntologyUndecidedDecisions,
|
|
8230
8271
|
ontology_business_rule_pass_rate_percent: deltaBusinessRulePassRate,
|
|
8231
8272
|
ontology_decision_resolved_rate_percent: deltaDecisionResolvedRate,
|
|
8273
|
+
moqui_matrix_regression_count: deltaMoquiMatrixRegressionCount,
|
|
8232
8274
|
scene_package_batch_failure_count: deltaSceneBatchFailureCount
|
|
8233
8275
|
}
|
|
8234
8276
|
};
|
|
@@ -8249,6 +8291,7 @@ function buildAutoHandoffRegressionWindowTrend(series = []) {
|
|
|
8249
8291
|
ontology_undecided_decisions: null,
|
|
8250
8292
|
ontology_business_rule_pass_rate_percent: null,
|
|
8251
8293
|
ontology_decision_resolved_rate_percent: null,
|
|
8294
|
+
moqui_matrix_regression_count: null,
|
|
8252
8295
|
scene_package_batch_failure_count: null
|
|
8253
8296
|
},
|
|
8254
8297
|
has_baseline: false
|
|
@@ -8290,6 +8333,9 @@ function buildAutoHandoffRegressionAggregates(series = []) {
|
|
|
8290
8333
|
const sceneBatchFailures = snapshots
|
|
8291
8334
|
.map(item => Number(item.scene_package_batch_failure_count))
|
|
8292
8335
|
.filter(value => Number.isFinite(value));
|
|
8336
|
+
const moquiMatrixRegressions = snapshots
|
|
8337
|
+
.map(item => Number(item.moqui_matrix_regression_count))
|
|
8338
|
+
.filter(value => Number.isFinite(value));
|
|
8293
8339
|
const sceneBatchApplicables = snapshots.filter(item => typeof item.scene_package_batch_passed === 'boolean');
|
|
8294
8340
|
const sceneBatchPassedCount = sceneBatchApplicables.filter(item => item.scene_package_batch_passed === true).length;
|
|
8295
8341
|
const sceneBatchFailedCount = sceneBatchApplicables.filter(item => item.scene_package_batch_passed === false).length;
|
|
@@ -8332,6 +8378,9 @@ function buildAutoHandoffRegressionAggregates(series = []) {
|
|
|
8332
8378
|
const averageSceneBatchFailures = sceneBatchFailures.length > 0
|
|
8333
8379
|
? Number((sceneBatchFailures.reduce((sum, value) => sum + value, 0) / sceneBatchFailures.length).toFixed(2))
|
|
8334
8380
|
: null;
|
|
8381
|
+
const averageMoquiMatrixRegressions = moquiMatrixRegressions.length > 0
|
|
8382
|
+
? Number((moquiMatrixRegressions.reduce((sum, value) => sum + value, 0) / moquiMatrixRegressions.length).toFixed(2))
|
|
8383
|
+
: null;
|
|
8335
8384
|
const sceneBatchPassRate = sceneBatchApplicables.length > 0
|
|
8336
8385
|
? Number(((sceneBatchPassedCount / sceneBatchApplicables.length) * 100).toFixed(2))
|
|
8337
8386
|
: null;
|
|
@@ -8356,6 +8405,8 @@ function buildAutoHandoffRegressionAggregates(series = []) {
|
|
|
8356
8405
|
scene_package_batch_pass_rate_percent: sceneBatchPassRate,
|
|
8357
8406
|
avg_scene_package_batch_failure_count: averageSceneBatchFailures,
|
|
8358
8407
|
max_scene_package_batch_failure_count: sceneBatchFailures.length > 0 ? Math.max(...sceneBatchFailures) : null,
|
|
8408
|
+
avg_moqui_matrix_regression_count: averageMoquiMatrixRegressions,
|
|
8409
|
+
max_moqui_matrix_regression_count: moquiMatrixRegressions.length > 0 ? Math.max(...moquiMatrixRegressions) : null,
|
|
8359
8410
|
risk_levels: riskLevels
|
|
8360
8411
|
};
|
|
8361
8412
|
}
|
|
@@ -8382,6 +8433,9 @@ function buildAutoHandoffRegressionRiskLayers(series = []) {
|
|
|
8382
8433
|
const sceneBatchFailures = scoped
|
|
8383
8434
|
.map(item => Number(item.scene_package_batch_failure_count))
|
|
8384
8435
|
.filter(value => Number.isFinite(value));
|
|
8436
|
+
const moquiMatrixRegressions = scoped
|
|
8437
|
+
.map(item => Number(item.moqui_matrix_regression_count))
|
|
8438
|
+
.filter(value => Number.isFinite(value));
|
|
8385
8439
|
const sceneBatchApplicable = scoped.filter(item => typeof item.scene_package_batch_passed === 'boolean');
|
|
8386
8440
|
const sceneBatchPassed = sceneBatchApplicable.filter(item => item.scene_package_batch_passed === true).length;
|
|
8387
8441
|
|
|
@@ -8400,6 +8454,8 @@ function buildAutoHandoffRegressionRiskLayers(series = []) {
|
|
|
8400
8454
|
avg_failed_goals: avg(failedGoals),
|
|
8401
8455
|
avg_ontology_quality_score: avg(ontologyScores),
|
|
8402
8456
|
avg_scene_package_batch_failure_count: avg(sceneBatchFailures),
|
|
8457
|
+
avg_moqui_matrix_regression_count: avg(moquiMatrixRegressions),
|
|
8458
|
+
max_moqui_matrix_regression_count: moquiMatrixRegressions.length > 0 ? Math.max(...moquiMatrixRegressions) : null,
|
|
8403
8459
|
scene_package_batch_pass_rate_percent: sceneBatchApplicable.length > 0
|
|
8404
8460
|
? Number(((sceneBatchPassed / sceneBatchApplicable.length) * 100).toFixed(2))
|
|
8405
8461
|
: null
|
|
@@ -8432,6 +8488,7 @@ function buildAutoHandoffRegressionRecommendations(payload = {}) {
|
|
|
8432
8488
|
const ontologyUnmappedRules = Number(current.ontology_unmapped_rules);
|
|
8433
8489
|
const ontologyUndecidedDecisions = Number(current.ontology_undecided_decisions);
|
|
8434
8490
|
const sceneBatchFailureCount = Number(current.scene_package_batch_failure_count);
|
|
8491
|
+
const moquiMatrixRegressionCount = Number(current.moqui_matrix_regression_count);
|
|
8435
8492
|
const sceneBatchPassed = current.scene_package_batch_passed;
|
|
8436
8493
|
|
|
8437
8494
|
if (trend === 'degraded' || windowTrend === 'degraded') {
|
|
@@ -8465,6 +8522,12 @@ function buildAutoHandoffRegressionRecommendations(payload = {}) {
|
|
|
8465
8522
|
'`sce scene package-publish-batch --manifest docs/handoffs/handoff-manifest.json --dry-run --json`.'
|
|
8466
8523
|
);
|
|
8467
8524
|
}
|
|
8525
|
+
if (Number.isFinite(moquiMatrixRegressionCount) && moquiMatrixRegressionCount > 0) {
|
|
8526
|
+
push(
|
|
8527
|
+
'Recover Moqui matrix regressions and rerun baseline gate: ' +
|
|
8528
|
+
'`sce scene moqui-baseline --include-all --compare-with .kiro/reports/release-evidence/moqui-template-baseline.json --json`.'
|
|
8529
|
+
);
|
|
8530
|
+
}
|
|
8468
8531
|
|
|
8469
8532
|
if ((payload.window && Number(payload.window.actual) > 0) && (payload.window.requested !== payload.window.actual)) {
|
|
8470
8533
|
push('Increase regression coverage with `sce auto handoff regression --window 10 --json`.');
|
|
@@ -8483,6 +8546,137 @@ function formatAutoHandoffRegressionValue(value, fallback = 'n/a') {
|
|
|
8483
8546
|
return `${value}`;
|
|
8484
8547
|
}
|
|
8485
8548
|
|
|
8549
|
+
function getAutoHandoffMoquiCoverageMatrix(summary = {}) {
|
|
8550
|
+
if (!summary || typeof summary !== 'object') {
|
|
8551
|
+
return {};
|
|
8552
|
+
}
|
|
8553
|
+
return summary.coverage_matrix && typeof summary.coverage_matrix === 'object'
|
|
8554
|
+
? summary.coverage_matrix
|
|
8555
|
+
: {};
|
|
8556
|
+
}
|
|
8557
|
+
|
|
8558
|
+
function getAutoHandoffMoquiCoverageMetric(summary = {}, metricName = '', field = 'rate_percent') {
|
|
8559
|
+
const matrix = getAutoHandoffMoquiCoverageMatrix(summary);
|
|
8560
|
+
const metric = matrix && matrix[metricName] && typeof matrix[metricName] === 'object'
|
|
8561
|
+
? matrix[metricName]
|
|
8562
|
+
: {};
|
|
8563
|
+
const value = Number(metric[field]);
|
|
8564
|
+
return Number.isFinite(value) ? value : null;
|
|
8565
|
+
}
|
|
8566
|
+
|
|
8567
|
+
function formatAutoHandoffMoquiCoverageMetric(summary = {}, metricName = '', field = 'rate_percent', suffix = '') {
|
|
8568
|
+
const value = getAutoHandoffMoquiCoverageMetric(summary, metricName, field);
|
|
8569
|
+
if (!Number.isFinite(value)) {
|
|
8570
|
+
return 'n/a';
|
|
8571
|
+
}
|
|
8572
|
+
return `${value}${suffix}`;
|
|
8573
|
+
}
|
|
8574
|
+
|
|
8575
|
+
function getAutoHandoffMoquiCoverageDeltaMatrix(compare = {}) {
|
|
8576
|
+
if (!compare || typeof compare !== 'object') {
|
|
8577
|
+
return {};
|
|
8578
|
+
}
|
|
8579
|
+
return compare.coverage_matrix_deltas && typeof compare.coverage_matrix_deltas === 'object'
|
|
8580
|
+
? compare.coverage_matrix_deltas
|
|
8581
|
+
: {};
|
|
8582
|
+
}
|
|
8583
|
+
|
|
8584
|
+
function getAutoHandoffMoquiCoverageDeltaMetric(compare = {}, metricName = '', field = 'rate_percent') {
|
|
8585
|
+
const matrix = getAutoHandoffMoquiCoverageDeltaMatrix(compare);
|
|
8586
|
+
const metric = matrix && matrix[metricName] && typeof matrix[metricName] === 'object'
|
|
8587
|
+
? matrix[metricName]
|
|
8588
|
+
: {};
|
|
8589
|
+
const value = Number(metric[field]);
|
|
8590
|
+
return Number.isFinite(value) ? value : null;
|
|
8591
|
+
}
|
|
8592
|
+
|
|
8593
|
+
function formatAutoHandoffMoquiCoverageDeltaMetric(compare = {}, metricName = '', field = 'rate_percent', suffix = '') {
|
|
8594
|
+
const value = getAutoHandoffMoquiCoverageDeltaMetric(compare, metricName, field);
|
|
8595
|
+
if (!Number.isFinite(value)) {
|
|
8596
|
+
return 'n/a';
|
|
8597
|
+
}
|
|
8598
|
+
return `${value}${suffix}`;
|
|
8599
|
+
}
|
|
8600
|
+
|
|
8601
|
+
function getAutoHandoffMoquiCoverageMetricLabel(metricName = '') {
|
|
8602
|
+
const labels = {
|
|
8603
|
+
graph_valid: 'graph-valid',
|
|
8604
|
+
score_passed: 'score-passed',
|
|
8605
|
+
entity_coverage: 'entity-coverage',
|
|
8606
|
+
relation_coverage: 'relation-coverage',
|
|
8607
|
+
business_rule_coverage: 'business-rule-coverage',
|
|
8608
|
+
business_rule_closed: 'business-rule-closed',
|
|
8609
|
+
decision_coverage: 'decision-coverage',
|
|
8610
|
+
decision_closed: 'decision-closed',
|
|
8611
|
+
baseline_passed: 'baseline-passed'
|
|
8612
|
+
};
|
|
8613
|
+
return labels[metricName] || metricName;
|
|
8614
|
+
}
|
|
8615
|
+
|
|
8616
|
+
function buildAutoHandoffMoquiCoverageRegressions(compare = {}) {
|
|
8617
|
+
const source = compare && typeof compare === 'object' ? compare : {};
|
|
8618
|
+
const predefined = Array.isArray(source.coverage_matrix_regressions)
|
|
8619
|
+
? source.coverage_matrix_regressions
|
|
8620
|
+
: null;
|
|
8621
|
+
if (predefined) {
|
|
8622
|
+
const normalized = predefined
|
|
8623
|
+
.map(item => {
|
|
8624
|
+
const metric = normalizeHandoffText(item && item.metric);
|
|
8625
|
+
const deltaRate = Number(item && item.delta_rate_percent);
|
|
8626
|
+
if (!metric || !Number.isFinite(deltaRate) || deltaRate >= 0) {
|
|
8627
|
+
return null;
|
|
8628
|
+
}
|
|
8629
|
+
return {
|
|
8630
|
+
metric,
|
|
8631
|
+
label: normalizeHandoffText(item && item.label) || getAutoHandoffMoquiCoverageMetricLabel(metric),
|
|
8632
|
+
delta_rate_percent: Number(deltaRate.toFixed(2))
|
|
8633
|
+
};
|
|
8634
|
+
})
|
|
8635
|
+
.filter(Boolean);
|
|
8636
|
+
if (normalized.length > 0) {
|
|
8637
|
+
return normalized.sort((a, b) => {
|
|
8638
|
+
if (a.delta_rate_percent !== b.delta_rate_percent) {
|
|
8639
|
+
return a.delta_rate_percent - b.delta_rate_percent;
|
|
8640
|
+
}
|
|
8641
|
+
return `${a.metric}`.localeCompare(`${b.metric}`);
|
|
8642
|
+
});
|
|
8643
|
+
}
|
|
8644
|
+
}
|
|
8645
|
+
|
|
8646
|
+
const deltaMatrix = getAutoHandoffMoquiCoverageDeltaMatrix(source);
|
|
8647
|
+
return Object.entries(deltaMatrix)
|
|
8648
|
+
.map(([metric, value]) => {
|
|
8649
|
+
const deltaRate = Number(value && value.rate_percent);
|
|
8650
|
+
if (!Number.isFinite(deltaRate) || deltaRate >= 0) {
|
|
8651
|
+
return null;
|
|
8652
|
+
}
|
|
8653
|
+
return {
|
|
8654
|
+
metric,
|
|
8655
|
+
label: getAutoHandoffMoquiCoverageMetricLabel(metric),
|
|
8656
|
+
delta_rate_percent: Number(deltaRate.toFixed(2))
|
|
8657
|
+
};
|
|
8658
|
+
})
|
|
8659
|
+
.filter(Boolean)
|
|
8660
|
+
.sort((a, b) => {
|
|
8661
|
+
if (a.delta_rate_percent !== b.delta_rate_percent) {
|
|
8662
|
+
return a.delta_rate_percent - b.delta_rate_percent;
|
|
8663
|
+
}
|
|
8664
|
+
return `${a.metric}`.localeCompare(`${b.metric}`);
|
|
8665
|
+
});
|
|
8666
|
+
}
|
|
8667
|
+
|
|
8668
|
+
function formatAutoHandoffMoquiCoverageRegressions(compare = {}, limit = 3) {
|
|
8669
|
+
const regressions = buildAutoHandoffMoquiCoverageRegressions(compare);
|
|
8670
|
+
if (regressions.length === 0) {
|
|
8671
|
+
return 'none';
|
|
8672
|
+
}
|
|
8673
|
+
const maxItems = Number.isFinite(Number(limit)) && Number(limit) > 0 ? Number(limit) : regressions.length;
|
|
8674
|
+
return regressions
|
|
8675
|
+
.slice(0, maxItems)
|
|
8676
|
+
.map(item => `${item.label}:${item.delta_rate_percent}%`)
|
|
8677
|
+
.join(' | ');
|
|
8678
|
+
}
|
|
8679
|
+
|
|
8486
8680
|
function renderAutoHandoffRegressionAsciiBar(value, max = 100, width = 20) {
|
|
8487
8681
|
const parsed = Number(value);
|
|
8488
8682
|
if (!Number.isFinite(parsed)) {
|
|
@@ -8530,7 +8724,8 @@ function renderAutoHandoffRegressionMarkdown(payload = {}) {
|
|
|
8530
8724
|
`avg_success=${formatAutoHandoffRegressionValue(scoped.avg_spec_success_rate_percent)}, ` +
|
|
8531
8725
|
`avg_failed_goals=${formatAutoHandoffRegressionValue(scoped.avg_failed_goals)}, ` +
|
|
8532
8726
|
`avg_ontology_quality=${formatAutoHandoffRegressionValue(scoped.avg_ontology_quality_score)}, ` +
|
|
8533
|
-
`scene_batch_pass_rate=${formatAutoHandoffRegressionValue(scoped.scene_package_batch_pass_rate_percent)}
|
|
8727
|
+
`scene_batch_pass_rate=${formatAutoHandoffRegressionValue(scoped.scene_package_batch_pass_rate_percent)}%, ` +
|
|
8728
|
+
`avg_moqui_matrix_regressions=${formatAutoHandoffRegressionValue(scoped.avg_moqui_matrix_regression_count, '0')}`
|
|
8534
8729
|
);
|
|
8535
8730
|
});
|
|
8536
8731
|
|
|
@@ -8551,6 +8746,7 @@ function renderAutoHandoffRegressionMarkdown(payload = {}) {
|
|
|
8551
8746
|
`- Ontology quality delta: ${formatAutoHandoffRegressionValue(delta.ontology_quality_score)}`,
|
|
8552
8747
|
`- Ontology unmapped rules delta: ${formatAutoHandoffRegressionValue(delta.ontology_unmapped_rules)}`,
|
|
8553
8748
|
`- Ontology undecided decisions delta: ${formatAutoHandoffRegressionValue(delta.ontology_undecided_decisions)}`,
|
|
8749
|
+
`- Moqui matrix regression count delta: ${formatAutoHandoffRegressionValue(delta.moqui_matrix_regression_count)}`,
|
|
8554
8750
|
`- Scene package batch failure count delta: ${formatAutoHandoffRegressionValue(delta.scene_package_batch_failure_count)}`,
|
|
8555
8751
|
'',
|
|
8556
8752
|
'## Window Trend',
|
|
@@ -8559,6 +8755,7 @@ function renderAutoHandoffRegressionMarkdown(payload = {}) {
|
|
|
8559
8755
|
`- Success rate delta: ${formatAutoHandoffRegressionValue(windowTrend.delta && windowTrend.delta.spec_success_rate_percent)}`,
|
|
8560
8756
|
`- Risk level rank delta: ${formatAutoHandoffRegressionValue(windowTrend.delta && windowTrend.delta.risk_level_rank)}`,
|
|
8561
8757
|
`- Failed goals delta: ${formatAutoHandoffRegressionValue(windowTrend.delta && windowTrend.delta.failed_goals)}`,
|
|
8758
|
+
`- Moqui matrix regression count delta: ${formatAutoHandoffRegressionValue(windowTrend.delta && windowTrend.delta.moqui_matrix_regression_count)}`,
|
|
8562
8759
|
'',
|
|
8563
8760
|
'## Aggregates',
|
|
8564
8761
|
'',
|
|
@@ -8578,6 +8775,8 @@ function renderAutoHandoffRegressionMarkdown(payload = {}) {
|
|
|
8578
8775
|
`- Scene package batch pass rate: ${formatAutoHandoffRegressionValue(aggregates.scene_package_batch_pass_rate_percent)}%`,
|
|
8579
8776
|
`- Scene package batch failed sessions: ${formatAutoHandoffRegressionValue(aggregates.scene_package_batch_failed_count, '0')}`,
|
|
8580
8777
|
`- Avg scene package batch failure count: ${formatAutoHandoffRegressionValue(aggregates.avg_scene_package_batch_failure_count)}`,
|
|
8778
|
+
`- Avg Moqui matrix regression count: ${formatAutoHandoffRegressionValue(aggregates.avg_moqui_matrix_regression_count)}`,
|
|
8779
|
+
`- Max Moqui matrix regression count: ${formatAutoHandoffRegressionValue(aggregates.max_moqui_matrix_regression_count)}`,
|
|
8581
8780
|
`- Risk levels: low=${formatAutoHandoffRegressionValue(riskLevels.low, '0')}, medium=${formatAutoHandoffRegressionValue(riskLevels.medium, '0')}, high=${formatAutoHandoffRegressionValue(riskLevels.high, '0')}, unknown=${formatAutoHandoffRegressionValue(riskLevels.unknown, '0')}`,
|
|
8582
8781
|
'',
|
|
8583
8782
|
'## Trend Series',
|
|
@@ -8755,6 +8954,24 @@ function buildAutoHandoffReleaseGateHistoryEntry(entry = {}, options = {}) {
|
|
|
8755
8954
|
? entry.scene_package_batch_failure_count
|
|
8756
8955
|
: signalMap.scene_package_batch_failure_count
|
|
8757
8956
|
);
|
|
8957
|
+
const capabilityExpectedUnknownCount = parseAutoHandoffGateNumber(
|
|
8958
|
+
entry.capability_expected_unknown_count !== undefined
|
|
8959
|
+
? entry.capability_expected_unknown_count
|
|
8960
|
+
: (
|
|
8961
|
+
signalMap.capability_expected_unknown_count !== undefined
|
|
8962
|
+
? signalMap.capability_expected_unknown_count
|
|
8963
|
+
: signalMap.capability_lexicon_expected_unknown_count
|
|
8964
|
+
)
|
|
8965
|
+
);
|
|
8966
|
+
const capabilityProvidedUnknownCount = parseAutoHandoffGateNumber(
|
|
8967
|
+
entry.capability_provided_unknown_count !== undefined
|
|
8968
|
+
? entry.capability_provided_unknown_count
|
|
8969
|
+
: (
|
|
8970
|
+
signalMap.capability_provided_unknown_count !== undefined
|
|
8971
|
+
? signalMap.capability_provided_unknown_count
|
|
8972
|
+
: signalMap.capability_lexicon_provided_unknown_count
|
|
8973
|
+
)
|
|
8974
|
+
);
|
|
8758
8975
|
const releaseGatePreflightAvailable = parseAutoHandoffGateBoolean(
|
|
8759
8976
|
entry.release_gate_preflight_available !== undefined
|
|
8760
8977
|
? entry.release_gate_preflight_available
|
|
@@ -8859,6 +9076,12 @@ function buildAutoHandoffReleaseGateHistoryEntry(entry = {}, options = {}) {
|
|
|
8859
9076
|
scene_package_batch_status: sceneBatchStatus || null,
|
|
8860
9077
|
scene_package_batch_passed: typeof sceneBatchPassed === 'boolean' ? sceneBatchPassed : null,
|
|
8861
9078
|
scene_package_batch_failure_count: Number.isFinite(sceneBatchFailureCount) ? sceneBatchFailureCount : null,
|
|
9079
|
+
capability_expected_unknown_count: Number.isFinite(capabilityExpectedUnknownCount)
|
|
9080
|
+
? Math.max(0, Number(capabilityExpectedUnknownCount))
|
|
9081
|
+
: null,
|
|
9082
|
+
capability_provided_unknown_count: Number.isFinite(capabilityProvidedUnknownCount)
|
|
9083
|
+
? Math.max(0, Number(capabilityProvidedUnknownCount))
|
|
9084
|
+
: null,
|
|
8862
9085
|
release_gate_preflight_available: typeof releaseGatePreflightAvailable === 'boolean'
|
|
8863
9086
|
? releaseGatePreflightAvailable
|
|
8864
9087
|
: null,
|
|
@@ -9021,6 +9244,12 @@ function buildAutoHandoffReleaseGateHistoryAggregates(entries = []) {
|
|
|
9021
9244
|
let preflightAvailableRuns = 0;
|
|
9022
9245
|
let preflightBlockedRuns = 0;
|
|
9023
9246
|
let preflightHardGateRuns = 0;
|
|
9247
|
+
let capabilityExpectedUnknownKnownRuns = 0;
|
|
9248
|
+
let capabilityExpectedUnknownPositiveRuns = 0;
|
|
9249
|
+
let capabilityProvidedUnknownKnownRuns = 0;
|
|
9250
|
+
let capabilityProvidedUnknownPositiveRuns = 0;
|
|
9251
|
+
const capabilityExpectedUnknownCounts = [];
|
|
9252
|
+
const capabilityProvidedUnknownCounts = [];
|
|
9024
9253
|
const sceneBatchFailureCounts = [];
|
|
9025
9254
|
let sceneBatchApplicableCount = 0;
|
|
9026
9255
|
let sceneBatchPassedCount = 0;
|
|
@@ -9069,6 +9298,28 @@ function buildAutoHandoffReleaseGateHistoryAggregates(entries = []) {
|
|
|
9069
9298
|
if (Number.isFinite(sceneBatchFailureCount)) {
|
|
9070
9299
|
sceneBatchFailureCounts.push(sceneBatchFailureCount);
|
|
9071
9300
|
}
|
|
9301
|
+
const capabilityExpectedUnknownCount = parseAutoHandoffGateNumber(
|
|
9302
|
+
entry && entry.capability_expected_unknown_count
|
|
9303
|
+
);
|
|
9304
|
+
if (Number.isFinite(capabilityExpectedUnknownCount)) {
|
|
9305
|
+
const normalizedCount = Math.max(0, Number(capabilityExpectedUnknownCount));
|
|
9306
|
+
capabilityExpectedUnknownKnownRuns += 1;
|
|
9307
|
+
capabilityExpectedUnknownCounts.push(normalizedCount);
|
|
9308
|
+
if (normalizedCount > 0) {
|
|
9309
|
+
capabilityExpectedUnknownPositiveRuns += 1;
|
|
9310
|
+
}
|
|
9311
|
+
}
|
|
9312
|
+
const capabilityProvidedUnknownCount = parseAutoHandoffGateNumber(
|
|
9313
|
+
entry && entry.capability_provided_unknown_count
|
|
9314
|
+
);
|
|
9315
|
+
if (Number.isFinite(capabilityProvidedUnknownCount)) {
|
|
9316
|
+
const normalizedCount = Math.max(0, Number(capabilityProvidedUnknownCount));
|
|
9317
|
+
capabilityProvidedUnknownKnownRuns += 1;
|
|
9318
|
+
capabilityProvidedUnknownCounts.push(normalizedCount);
|
|
9319
|
+
if (normalizedCount > 0) {
|
|
9320
|
+
capabilityProvidedUnknownPositiveRuns += 1;
|
|
9321
|
+
}
|
|
9322
|
+
}
|
|
9072
9323
|
const preflightAvailable = parseAutoHandoffGateBoolean(
|
|
9073
9324
|
entry && entry.release_gate_preflight_available,
|
|
9074
9325
|
null
|
|
@@ -9149,6 +9400,24 @@ function buildAutoHandoffReleaseGateHistoryAggregates(entries = []) {
|
|
|
9149
9400
|
const maxSceneBatchFailureCount = sceneBatchFailureCounts.length > 0
|
|
9150
9401
|
? Number(Math.max(...sceneBatchFailureCounts).toFixed(2))
|
|
9151
9402
|
: null;
|
|
9403
|
+
const avgCapabilityExpectedUnknownCount = capabilityExpectedUnknownCounts.length > 0
|
|
9404
|
+
? Number((capabilityExpectedUnknownCounts.reduce((sum, value) => sum + value, 0) / capabilityExpectedUnknownCounts.length).toFixed(2))
|
|
9405
|
+
: null;
|
|
9406
|
+
const maxCapabilityExpectedUnknownCount = capabilityExpectedUnknownCounts.length > 0
|
|
9407
|
+
? Number(Math.max(...capabilityExpectedUnknownCounts).toFixed(2))
|
|
9408
|
+
: null;
|
|
9409
|
+
const capabilityExpectedUnknownPositiveRate = capabilityExpectedUnknownKnownRuns > 0
|
|
9410
|
+
? Number(((capabilityExpectedUnknownPositiveRuns / capabilityExpectedUnknownKnownRuns) * 100).toFixed(2))
|
|
9411
|
+
: null;
|
|
9412
|
+
const avgCapabilityProvidedUnknownCount = capabilityProvidedUnknownCounts.length > 0
|
|
9413
|
+
? Number((capabilityProvidedUnknownCounts.reduce((sum, value) => sum + value, 0) / capabilityProvidedUnknownCounts.length).toFixed(2))
|
|
9414
|
+
: null;
|
|
9415
|
+
const maxCapabilityProvidedUnknownCount = capabilityProvidedUnknownCounts.length > 0
|
|
9416
|
+
? Number(Math.max(...capabilityProvidedUnknownCounts).toFixed(2))
|
|
9417
|
+
: null;
|
|
9418
|
+
const capabilityProvidedUnknownPositiveRate = capabilityProvidedUnknownKnownRuns > 0
|
|
9419
|
+
? Number(((capabilityProvidedUnknownPositiveRuns / capabilityProvidedUnknownKnownRuns) * 100).toFixed(2))
|
|
9420
|
+
: null;
|
|
9152
9421
|
const driftAlertRate = driftKnownRuns > 0
|
|
9153
9422
|
? Number(((driftAlertRuns / driftKnownRuns) * 100).toFixed(2))
|
|
9154
9423
|
: null;
|
|
@@ -9181,6 +9450,16 @@ function buildAutoHandoffReleaseGateHistoryAggregates(entries = []) {
|
|
|
9181
9450
|
scene_package_batch_pass_rate_percent: sceneBatchPassRate,
|
|
9182
9451
|
avg_scene_package_batch_failure_count: avgSceneBatchFailureCount,
|
|
9183
9452
|
max_scene_package_batch_failure_count: maxSceneBatchFailureCount,
|
|
9453
|
+
capability_expected_unknown_known_runs: capabilityExpectedUnknownKnownRuns,
|
|
9454
|
+
capability_expected_unknown_positive_runs: capabilityExpectedUnknownPositiveRuns,
|
|
9455
|
+
capability_expected_unknown_positive_rate_percent: capabilityExpectedUnknownPositiveRate,
|
|
9456
|
+
avg_capability_expected_unknown_count: avgCapabilityExpectedUnknownCount,
|
|
9457
|
+
max_capability_expected_unknown_count: maxCapabilityExpectedUnknownCount,
|
|
9458
|
+
capability_provided_unknown_known_runs: capabilityProvidedUnknownKnownRuns,
|
|
9459
|
+
capability_provided_unknown_positive_runs: capabilityProvidedUnknownPositiveRuns,
|
|
9460
|
+
capability_provided_unknown_positive_rate_percent: capabilityProvidedUnknownPositiveRate,
|
|
9461
|
+
avg_capability_provided_unknown_count: avgCapabilityProvidedUnknownCount,
|
|
9462
|
+
max_capability_provided_unknown_count: maxCapabilityProvidedUnknownCount,
|
|
9184
9463
|
drift_known_runs: driftKnownRuns,
|
|
9185
9464
|
drift_alert_total: driftAlertTotal,
|
|
9186
9465
|
drift_alert_runs: driftAlertRuns,
|
|
@@ -9246,6 +9525,8 @@ async function buildAutoHandoffReleaseGateHistoryIndex(projectPath, options = {}
|
|
|
9246
9525
|
risk_level: latestEntry.risk_level,
|
|
9247
9526
|
scene_package_batch_passed: latestEntry.scene_package_batch_passed,
|
|
9248
9527
|
scene_package_batch_failure_count: latestEntry.scene_package_batch_failure_count,
|
|
9528
|
+
capability_expected_unknown_count: latestEntry.capability_expected_unknown_count,
|
|
9529
|
+
capability_provided_unknown_count: latestEntry.capability_provided_unknown_count,
|
|
9249
9530
|
release_gate_preflight_available: latestEntry.release_gate_preflight_available,
|
|
9250
9531
|
release_gate_preflight_blocked: latestEntry.release_gate_preflight_blocked,
|
|
9251
9532
|
require_release_gate_preflight: latestEntry.require_release_gate_preflight,
|
|
@@ -9291,6 +9572,8 @@ function renderAutoHandoffReleaseGateHistoryMarkdown(payload = {}) {
|
|
|
9291
9572
|
lines.push(`- Risk level: ${formatAutoHandoffRegressionValue(latest.risk_level)}`);
|
|
9292
9573
|
lines.push(`- Scene package batch: ${latest.scene_package_batch_passed === true ? 'pass' : (latest.scene_package_batch_passed === false ? 'fail' : 'n/a')}`);
|
|
9293
9574
|
lines.push(`- Scene package batch failures: ${formatAutoHandoffRegressionValue(latest.scene_package_batch_failure_count)}`);
|
|
9575
|
+
lines.push(`- Capability expected unknown count: ${formatAutoHandoffRegressionValue(latest.capability_expected_unknown_count, '0')}`);
|
|
9576
|
+
lines.push(`- Capability provided unknown count: ${formatAutoHandoffRegressionValue(latest.capability_provided_unknown_count, '0')}`);
|
|
9294
9577
|
lines.push(`- Release preflight available: ${latest.release_gate_preflight_available === true ? 'yes' : (latest.release_gate_preflight_available === false ? 'no' : 'n/a')}`);
|
|
9295
9578
|
lines.push(`- Release preflight blocked: ${latest.release_gate_preflight_blocked === true ? 'yes' : (latest.release_gate_preflight_blocked === false ? 'no' : 'n/a')}`);
|
|
9296
9579
|
lines.push(`- Release preflight hard-gate: ${latest.require_release_gate_preflight === true ? 'enabled' : (latest.require_release_gate_preflight === false ? 'advisory' : 'n/a')}`);
|
|
@@ -9312,6 +9595,12 @@ function renderAutoHandoffReleaseGateHistoryMarkdown(payload = {}) {
|
|
|
9312
9595
|
lines.push(`- Scene package batch pass rate: ${formatAutoHandoffRegressionValue(aggregates.scene_package_batch_pass_rate_percent)}%`);
|
|
9313
9596
|
lines.push(`- Scene package batch failed: ${formatAutoHandoffRegressionValue(aggregates.scene_package_batch_failed_count, '0')}`);
|
|
9314
9597
|
lines.push(`- Avg scene package batch failures: ${formatAutoHandoffRegressionValue(aggregates.avg_scene_package_batch_failure_count)}`);
|
|
9598
|
+
lines.push(`- Capability expected unknown positive rate: ${formatAutoHandoffRegressionValue(aggregates.capability_expected_unknown_positive_rate_percent)}%`);
|
|
9599
|
+
lines.push(`- Avg capability expected unknown count: ${formatAutoHandoffRegressionValue(aggregates.avg_capability_expected_unknown_count)}`);
|
|
9600
|
+
lines.push(`- Max capability expected unknown count: ${formatAutoHandoffRegressionValue(aggregates.max_capability_expected_unknown_count)}`);
|
|
9601
|
+
lines.push(`- Capability provided unknown positive rate: ${formatAutoHandoffRegressionValue(aggregates.capability_provided_unknown_positive_rate_percent)}%`);
|
|
9602
|
+
lines.push(`- Avg capability provided unknown count: ${formatAutoHandoffRegressionValue(aggregates.avg_capability_provided_unknown_count)}`);
|
|
9603
|
+
lines.push(`- Max capability provided unknown count: ${formatAutoHandoffRegressionValue(aggregates.max_capability_provided_unknown_count)}`);
|
|
9315
9604
|
lines.push(`- Drift alert runs: ${formatAutoHandoffRegressionValue(aggregates.drift_alert_runs, '0')}`);
|
|
9316
9605
|
lines.push(`- Drift blocked runs: ${formatAutoHandoffRegressionValue(aggregates.drift_blocked_runs, '0')}`);
|
|
9317
9606
|
lines.push(`- Drift alert rate: ${formatAutoHandoffRegressionValue(aggregates.drift_alert_rate_percent)}%`);
|
|
@@ -9343,6 +9632,14 @@ function renderAutoHandoffReleaseGateHistoryMarkdown(payload = {}) {
|
|
|
9343
9632
|
const sceneBatchFailures = formatAutoHandoffRegressionValue(
|
|
9344
9633
|
entry && entry.scene_package_batch_failure_count
|
|
9345
9634
|
);
|
|
9635
|
+
const capabilityExpectedUnknown = formatAutoHandoffRegressionValue(
|
|
9636
|
+
entry && entry.capability_expected_unknown_count,
|
|
9637
|
+
'0'
|
|
9638
|
+
);
|
|
9639
|
+
const capabilityProvidedUnknown = formatAutoHandoffRegressionValue(
|
|
9640
|
+
entry && entry.capability_provided_unknown_count,
|
|
9641
|
+
'0'
|
|
9642
|
+
);
|
|
9346
9643
|
const preflightBlocked = entry && entry.release_gate_preflight_blocked === true
|
|
9347
9644
|
? 'yes'
|
|
9348
9645
|
: (entry && entry.release_gate_preflight_blocked === false ? 'no' : 'n/a');
|
|
@@ -9355,7 +9652,8 @@ function renderAutoHandoffReleaseGateHistoryMarkdown(payload = {}) {
|
|
|
9355
9652
|
: (entry && entry.drift_blocked === false ? 'no' : 'n/a');
|
|
9356
9653
|
lines.push(
|
|
9357
9654
|
`- ${tag} | passed=${passed} | risk=${risk} | scene-batch=${sceneBatch} | ` +
|
|
9358
|
-
`scene-failures=${sceneBatchFailures} |
|
|
9655
|
+
`scene-failures=${sceneBatchFailures} | capability-unknown=${capabilityExpectedUnknown}/${capabilityProvidedUnknown} | ` +
|
|
9656
|
+
`preflight-blocked=${preflightBlocked} | hard-gate=${preflightHardGate} | ` +
|
|
9359
9657
|
`drift-alerts=${driftAlerts} | drift-blocked=${driftBlocked} | ` +
|
|
9360
9658
|
`success=${successRate} | violations=${violations} | at=${evaluatedAt}`
|
|
9361
9659
|
);
|
|
@@ -9426,6 +9724,13 @@ function buildAutoHandoffEvidenceSnapshot(entry = {}) {
|
|
|
9426
9724
|
const ontologyMetrics = ontology && typeof ontology.metrics === 'object'
|
|
9427
9725
|
? ontology.metrics
|
|
9428
9726
|
: {};
|
|
9727
|
+
const moquiBaseline = entry && typeof entry.moqui_baseline === 'object'
|
|
9728
|
+
? entry.moqui_baseline
|
|
9729
|
+
: {};
|
|
9730
|
+
const moquiCompare = moquiBaseline && typeof moquiBaseline.compare === 'object'
|
|
9731
|
+
? moquiBaseline.compare
|
|
9732
|
+
: {};
|
|
9733
|
+
const moquiMatrixRegressions = buildAutoHandoffMoquiCoverageRegressions(moquiCompare);
|
|
9429
9734
|
const scenePackageBatch = entry && typeof entry.scene_package_batch === 'object'
|
|
9430
9735
|
? entry.scene_package_batch
|
|
9431
9736
|
: {};
|
|
@@ -9490,6 +9795,7 @@ function buildAutoHandoffEvidenceSnapshot(entry = {}) {
|
|
|
9490
9795
|
entry.capability_coverage.summary &&
|
|
9491
9796
|
entry.capability_coverage.summary.passed === true
|
|
9492
9797
|
),
|
|
9798
|
+
moqui_matrix_regression_count: moquiMatrixRegressions.length,
|
|
9493
9799
|
generated_at: normalizeHandoffText(entry.merged_at)
|
|
9494
9800
|
};
|
|
9495
9801
|
}
|
|
@@ -9534,6 +9840,9 @@ function renderAutoHandoffEvidenceReviewMarkdown(payload = {}) {
|
|
|
9534
9840
|
const failureSummary = currentOverview.failure_summary && typeof currentOverview.failure_summary === 'object'
|
|
9535
9841
|
? currentOverview.failure_summary
|
|
9536
9842
|
: {};
|
|
9843
|
+
const currentPolicy = currentOverview.policy && typeof currentOverview.policy === 'object'
|
|
9844
|
+
? currentOverview.policy
|
|
9845
|
+
: {};
|
|
9537
9846
|
const ontology = currentOverview.ontology_validation && typeof currentOverview.ontology_validation === 'object'
|
|
9538
9847
|
? currentOverview.ontology_validation
|
|
9539
9848
|
: {};
|
|
@@ -9549,9 +9858,16 @@ function renderAutoHandoffEvidenceReviewMarkdown(payload = {}) {
|
|
|
9549
9858
|
const moquiSummary = moquiBaseline && moquiBaseline.summary && typeof moquiBaseline.summary === 'object'
|
|
9550
9859
|
? moquiBaseline.summary
|
|
9551
9860
|
: {};
|
|
9861
|
+
const moquiScopeBreakdown = moquiSummary && moquiSummary.scope_breakdown && typeof moquiSummary.scope_breakdown === 'object'
|
|
9862
|
+
? moquiSummary.scope_breakdown
|
|
9863
|
+
: {};
|
|
9864
|
+
const moquiGapFrequency = Array.isArray(moquiSummary && moquiSummary.gap_frequency)
|
|
9865
|
+
? moquiSummary.gap_frequency
|
|
9866
|
+
: [];
|
|
9552
9867
|
const moquiCompare = moquiBaseline && moquiBaseline.compare && typeof moquiBaseline.compare === 'object'
|
|
9553
9868
|
? moquiBaseline.compare
|
|
9554
9869
|
: {};
|
|
9870
|
+
const moquiMatrixRegressions = buildAutoHandoffMoquiCoverageRegressions(moquiCompare);
|
|
9555
9871
|
const moquiDeltas = moquiCompare && moquiCompare.deltas && typeof moquiCompare.deltas === 'object'
|
|
9556
9872
|
? moquiCompare.deltas
|
|
9557
9873
|
: {};
|
|
@@ -9634,7 +9950,8 @@ function renderAutoHandoffEvidenceReviewMarkdown(payload = {}) {
|
|
|
9634
9950
|
`avg_success=${formatAutoHandoffRegressionValue(scoped.avg_spec_success_rate_percent)}, ` +
|
|
9635
9951
|
`avg_failed_goals=${formatAutoHandoffRegressionValue(scoped.avg_failed_goals)}, ` +
|
|
9636
9952
|
`avg_ontology_quality=${formatAutoHandoffRegressionValue(scoped.avg_ontology_quality_score)}, ` +
|
|
9637
|
-
`scene_batch_pass_rate=${formatAutoHandoffRegressionValue(scoped.scene_package_batch_pass_rate_percent)}
|
|
9953
|
+
`scene_batch_pass_rate=${formatAutoHandoffRegressionValue(scoped.scene_package_batch_pass_rate_percent)}%, ` +
|
|
9954
|
+
`avg_moqui_matrix_regressions=${formatAutoHandoffRegressionValue(scoped.avg_moqui_matrix_regression_count, '0')}`
|
|
9638
9955
|
);
|
|
9639
9956
|
});
|
|
9640
9957
|
|
|
@@ -9700,10 +10017,24 @@ function renderAutoHandoffEvidenceReviewMarkdown(payload = {}) {
|
|
|
9700
10017
|
`- Avg score: ${formatAutoHandoffRegressionValue(moquiSummary.avg_score)}`,
|
|
9701
10018
|
`- Valid-rate: ${formatAutoHandoffRegressionValue(moquiSummary.valid_rate_percent)}%`,
|
|
9702
10019
|
`- Baseline failed templates: ${formatAutoHandoffRegressionValue(moquiSummary.baseline_failed)}`,
|
|
10020
|
+
`- Matrix regression count: ${formatAutoHandoffRegressionValue(moquiMatrixRegressions.length, '0')}`,
|
|
10021
|
+
`- Matrix regression gate (max): ${formatAutoHandoffRegressionValue(currentPolicy.max_moqui_matrix_regressions)}`,
|
|
10022
|
+
`- Scope mix (moqui/suite/other): ${formatAutoHandoffRegressionValue(moquiScopeBreakdown.moqui_erp, '0')}/${formatAutoHandoffRegressionValue(moquiScopeBreakdown.scene_orchestration, '0')}/${formatAutoHandoffRegressionValue(moquiScopeBreakdown.other, '0')}`,
|
|
10023
|
+
`- Entity coverage: ${formatAutoHandoffMoquiCoverageMetric(moquiSummary, 'entity_coverage', 'rate_percent', '%')}`,
|
|
10024
|
+
`- Relation coverage: ${formatAutoHandoffMoquiCoverageMetric(moquiSummary, 'relation_coverage', 'rate_percent', '%')}`,
|
|
10025
|
+
`- Business-rule coverage: ${formatAutoHandoffMoquiCoverageMetric(moquiSummary, 'business_rule_coverage', 'rate_percent', '%')}`,
|
|
10026
|
+
`- Business-rule closed: ${formatAutoHandoffMoquiCoverageMetric(moquiSummary, 'business_rule_closed', 'rate_percent', '%')}`,
|
|
10027
|
+
`- Decision coverage: ${formatAutoHandoffMoquiCoverageMetric(moquiSummary, 'decision_coverage', 'rate_percent', '%')}`,
|
|
10028
|
+
`- Decision closed: ${formatAutoHandoffMoquiCoverageMetric(moquiSummary, 'decision_closed', 'rate_percent', '%')}`,
|
|
9703
10029
|
`- Delta avg score: ${formatAutoHandoffRegressionValue(moquiDeltas.avg_score)}`,
|
|
9704
10030
|
`- Delta valid-rate: ${formatAutoHandoffRegressionValue(moquiDeltas.valid_rate_percent)}%`,
|
|
10031
|
+
`- Delta entity coverage: ${formatAutoHandoffMoquiCoverageDeltaMetric(moquiCompare, 'entity_coverage', 'rate_percent', '%')}`,
|
|
10032
|
+
`- Delta business-rule closed: ${formatAutoHandoffMoquiCoverageDeltaMetric(moquiCompare, 'business_rule_closed', 'rate_percent', '%')}`,
|
|
10033
|
+
`- Delta decision closed: ${formatAutoHandoffMoquiCoverageDeltaMetric(moquiCompare, 'decision_closed', 'rate_percent', '%')}`,
|
|
10034
|
+
`- Matrix regressions: ${formatAutoHandoffMoquiCoverageRegressions(moquiCompare, 5)}`,
|
|
9705
10035
|
`- Newly failed templates: ${Array.isArray(moquiFailedTemplates.newly_failed) && moquiFailedTemplates.newly_failed.length > 0 ? moquiFailedTemplates.newly_failed.join(', ') : 'none'}`,
|
|
9706
10036
|
`- Recovered templates: ${Array.isArray(moquiFailedTemplates.recovered) && moquiFailedTemplates.recovered.length > 0 ? moquiFailedTemplates.recovered.join(', ') : 'none'}`,
|
|
10037
|
+
`- Top baseline gaps: ${moquiGapFrequency.length > 0 ? moquiGapFrequency.slice(0, 3).map(item => `${item.gap}:${item.count}`).join(' | ') : 'none'}`,
|
|
9707
10038
|
`- Baseline JSON: ${formatAutoHandoffRegressionValue(moquiBaseline.output && moquiBaseline.output.json)}`,
|
|
9708
10039
|
'',
|
|
9709
10040
|
'## Current Scene Package Batch',
|
|
@@ -9860,9 +10191,16 @@ function renderAutoHandoffReleaseNotesDraft(payload = {}, context = {}) {
|
|
|
9860
10191
|
const moquiSummary = moquiBaseline && moquiBaseline.summary && typeof moquiBaseline.summary === 'object'
|
|
9861
10192
|
? moquiBaseline.summary
|
|
9862
10193
|
: {};
|
|
10194
|
+
const moquiScopeBreakdown = moquiSummary && moquiSummary.scope_breakdown && typeof moquiSummary.scope_breakdown === 'object'
|
|
10195
|
+
? moquiSummary.scope_breakdown
|
|
10196
|
+
: {};
|
|
10197
|
+
const moquiGapFrequency = Array.isArray(moquiSummary && moquiSummary.gap_frequency)
|
|
10198
|
+
? moquiSummary.gap_frequency
|
|
10199
|
+
: [];
|
|
9863
10200
|
const moquiCompare = moquiBaseline && moquiBaseline.compare && typeof moquiBaseline.compare === 'object'
|
|
9864
10201
|
? moquiBaseline.compare
|
|
9865
10202
|
: {};
|
|
10203
|
+
const moquiMatrixRegressions = buildAutoHandoffMoquiCoverageRegressions(moquiCompare);
|
|
9866
10204
|
const moquiDeltas = moquiCompare && moquiCompare.deltas && typeof moquiCompare.deltas === 'object'
|
|
9867
10205
|
? moquiCompare.deltas
|
|
9868
10206
|
: {};
|
|
@@ -9933,7 +10271,8 @@ function renderAutoHandoffReleaseNotesDraft(payload = {}, context = {}) {
|
|
|
9933
10271
|
`- ${level}: count=${formatAutoHandoffRegressionValue(scoped.count, '0')}, ` +
|
|
9934
10272
|
`avg_success=${formatAutoHandoffRegressionValue(scoped.avg_spec_success_rate_percent)}, ` +
|
|
9935
10273
|
`avg_failed_goals=${formatAutoHandoffRegressionValue(scoped.avg_failed_goals)}, ` +
|
|
9936
|
-
`avg_ontology_quality=${formatAutoHandoffRegressionValue(scoped.avg_ontology_quality_score)}`
|
|
10274
|
+
`avg_ontology_quality=${formatAutoHandoffRegressionValue(scoped.avg_ontology_quality_score)}, ` +
|
|
10275
|
+
`avg_moqui_matrix_regressions=${formatAutoHandoffRegressionValue(scoped.avg_moqui_matrix_regression_count, '0')}`
|
|
9937
10276
|
);
|
|
9938
10277
|
});
|
|
9939
10278
|
|
|
@@ -9965,9 +10304,23 @@ function renderAutoHandoffReleaseNotesDraft(payload = {}, context = {}) {
|
|
|
9965
10304
|
`- Moqui baseline avg score: ${formatAutoHandoffRegressionValue(moquiSummary.avg_score)}`,
|
|
9966
10305
|
`- Moqui baseline valid-rate: ${formatAutoHandoffRegressionValue(moquiSummary.valid_rate_percent)}%`,
|
|
9967
10306
|
`- Moqui baseline failed templates: ${formatAutoHandoffRegressionValue(moquiSummary.baseline_failed)}`,
|
|
10307
|
+
`- Moqui matrix regression count: ${formatAutoHandoffRegressionValue(moquiMatrixRegressions.length, '0')}`,
|
|
10308
|
+
`- Moqui matrix regression gate (max): ${formatAutoHandoffRegressionValue(currentPolicy.max_moqui_matrix_regressions)}`,
|
|
10309
|
+
`- Moqui scope mix (moqui/suite/other): ${formatAutoHandoffRegressionValue(moquiScopeBreakdown.moqui_erp, '0')}/${formatAutoHandoffRegressionValue(moquiScopeBreakdown.scene_orchestration, '0')}/${formatAutoHandoffRegressionValue(moquiScopeBreakdown.other, '0')}`,
|
|
10310
|
+
`- Moqui entity coverage: ${formatAutoHandoffMoquiCoverageMetric(moquiSummary, 'entity_coverage', 'rate_percent', '%')}`,
|
|
10311
|
+
`- Moqui relation coverage: ${formatAutoHandoffMoquiCoverageMetric(moquiSummary, 'relation_coverage', 'rate_percent', '%')}`,
|
|
10312
|
+
`- Moqui business-rule coverage: ${formatAutoHandoffMoquiCoverageMetric(moquiSummary, 'business_rule_coverage', 'rate_percent', '%')}`,
|
|
10313
|
+
`- Moqui business-rule closed: ${formatAutoHandoffMoquiCoverageMetric(moquiSummary, 'business_rule_closed', 'rate_percent', '%')}`,
|
|
10314
|
+
`- Moqui decision coverage: ${formatAutoHandoffMoquiCoverageMetric(moquiSummary, 'decision_coverage', 'rate_percent', '%')}`,
|
|
10315
|
+
`- Moqui decision closed: ${formatAutoHandoffMoquiCoverageMetric(moquiSummary, 'decision_closed', 'rate_percent', '%')}`,
|
|
9968
10316
|
`- Moqui baseline avg score delta: ${formatAutoHandoffRegressionValue(moquiDeltas.avg_score)}`,
|
|
9969
10317
|
`- Moqui baseline valid-rate delta: ${formatAutoHandoffRegressionValue(moquiDeltas.valid_rate_percent)}%`,
|
|
10318
|
+
`- Moqui entity coverage delta: ${formatAutoHandoffMoquiCoverageDeltaMetric(moquiCompare, 'entity_coverage', 'rate_percent', '%')}`,
|
|
10319
|
+
`- Moqui business-rule closed delta: ${formatAutoHandoffMoquiCoverageDeltaMetric(moquiCompare, 'business_rule_closed', 'rate_percent', '%')}`,
|
|
10320
|
+
`- Moqui decision closed delta: ${formatAutoHandoffMoquiCoverageDeltaMetric(moquiCompare, 'decision_closed', 'rate_percent', '%')}`,
|
|
10321
|
+
`- Moqui matrix regressions: ${formatAutoHandoffMoquiCoverageRegressions(moquiCompare, 5)}`,
|
|
9970
10322
|
`- Moqui newly failed templates: ${Array.isArray(moquiFailedTemplates.newly_failed) && moquiFailedTemplates.newly_failed.length > 0 ? moquiFailedTemplates.newly_failed.join(', ') : 'none'}`,
|
|
10323
|
+
`- Moqui top baseline gaps: ${moquiGapFrequency.length > 0 ? moquiGapFrequency.slice(0, 3).map(item => `${item.gap}:${item.count}`).join(' | ') : 'none'}`,
|
|
9971
10324
|
`- Scene package batch status: ${formatAutoHandoffRegressionValue(scenePackageBatch.status)}`,
|
|
9972
10325
|
`- Scene package batch selected: ${formatAutoHandoffRegressionValue(scenePackageBatchSummary.selected)}`,
|
|
9973
10326
|
`- Scene package batch failed: ${formatAutoHandoffRegressionValue(scenePackageBatchSummary.failed)}`,
|
|
@@ -10279,6 +10632,17 @@ function normalizeHandoffMinCapabilitySemantic(semanticCandidate) {
|
|
|
10279
10632
|
return Number(parsed.toFixed(2));
|
|
10280
10633
|
}
|
|
10281
10634
|
|
|
10635
|
+
function normalizeHandoffMaxMoquiMatrixRegressions(valueCandidate) {
|
|
10636
|
+
if (valueCandidate === undefined || valueCandidate === null || valueCandidate === '') {
|
|
10637
|
+
return 0;
|
|
10638
|
+
}
|
|
10639
|
+
const parsed = Number(valueCandidate);
|
|
10640
|
+
if (!Number.isInteger(parsed) || parsed < 0) {
|
|
10641
|
+
throw new Error('--max-moqui-matrix-regressions must be an integer >= 0.');
|
|
10642
|
+
}
|
|
10643
|
+
return parsed;
|
|
10644
|
+
}
|
|
10645
|
+
|
|
10282
10646
|
function normalizeHandoffOptionalNonNegativeInteger(valueCandidate, optionName) {
|
|
10283
10647
|
if (valueCandidate === undefined || valueCandidate === null || valueCandidate === '') {
|
|
10284
10648
|
return null;
|
|
@@ -10307,6 +10671,7 @@ function buildAutoHandoffRunPolicy(options = {}) {
|
|
|
10307
10671
|
max_risk_level: normalizeHandoffRiskLevel(options.maxRiskLevel),
|
|
10308
10672
|
min_ontology_score: normalizeHandoffMinOntologyScore(options.minOntologyScore),
|
|
10309
10673
|
min_capability_coverage_percent: normalizeHandoffMinCapabilityCoverage(options.minCapabilityCoverage),
|
|
10674
|
+
max_moqui_matrix_regressions: normalizeHandoffMaxMoquiMatrixRegressions(options.maxMoquiMatrixRegressions),
|
|
10310
10675
|
max_unmapped_rules: normalizeHandoffOptionalNonNegativeInteger(
|
|
10311
10676
|
options.maxUnmappedRules,
|
|
10312
10677
|
'--max-unmapped-rules'
|
|
@@ -10319,6 +10684,7 @@ function buildAutoHandoffRunPolicy(options = {}) {
|
|
|
10319
10684
|
require_moqui_baseline: options.requireMoquiBaseline !== false,
|
|
10320
10685
|
require_scene_package_batch: options.requireScenePackageBatch !== false,
|
|
10321
10686
|
require_capability_coverage: options.requireCapabilityCoverage !== false,
|
|
10687
|
+
require_capability_lexicon: options.requireCapabilityLexicon !== false,
|
|
10322
10688
|
require_release_gate_preflight: options.requireReleaseGatePreflight === true,
|
|
10323
10689
|
dependency_batching: options.dependencyBatching !== false,
|
|
10324
10690
|
release_evidence_window: normalizeHandoffReleaseEvidenceWindow(options.releaseEvidenceWindow)
|
|
@@ -10635,6 +11001,10 @@ function evaluateAutoHandoffMoquiBaselineGateReasons(policy = {}, moquiBaseline
|
|
|
10635
11001
|
const summary = baseline && baseline.summary && typeof baseline.summary === 'object'
|
|
10636
11002
|
? baseline.summary
|
|
10637
11003
|
: {};
|
|
11004
|
+
const compare = baseline && baseline.compare && typeof baseline.compare === 'object'
|
|
11005
|
+
? baseline.compare
|
|
11006
|
+
: {};
|
|
11007
|
+
const matrixRegressions = buildAutoHandoffMoquiCoverageRegressions(compare);
|
|
10638
11008
|
const status = `${baseline && baseline.status ? baseline.status : 'missing'}`.trim().toLowerCase();
|
|
10639
11009
|
if (!baseline || baseline.generated !== true) {
|
|
10640
11010
|
const reason = baseline && baseline.reason ? baseline.reason : 'moqui baseline snapshot missing';
|
|
@@ -10653,6 +11023,15 @@ function evaluateAutoHandoffMoquiBaselineGateReasons(policy = {}, moquiBaseline
|
|
|
10653
11023
|
`valid_rate=${Number.isFinite(validRate) ? `${validRate}%` : 'n/a'})`
|
|
10654
11024
|
);
|
|
10655
11025
|
}
|
|
11026
|
+
if (Number.isInteger(policy.max_moqui_matrix_regressions)) {
|
|
11027
|
+
const limit = Number(policy.max_moqui_matrix_regressions);
|
|
11028
|
+
if (matrixRegressions.length > limit) {
|
|
11029
|
+
reasons.push(
|
|
11030
|
+
`moqui baseline matrix regressions ${matrixRegressions.length} > allowed ${limit} ` +
|
|
11031
|
+
`(${matrixRegressions.slice(0, 3).map(item => `${item.label}:${item.delta_rate_percent}%`).join(' | ')})`
|
|
11032
|
+
);
|
|
11033
|
+
}
|
|
11034
|
+
}
|
|
10656
11035
|
return reasons;
|
|
10657
11036
|
}
|
|
10658
11037
|
|
|
@@ -10734,6 +11113,57 @@ function evaluateAutoHandoffCapabilityCoverageGateReasons(policy = {}, capabilit
|
|
|
10734
11113
|
return reasons;
|
|
10735
11114
|
}
|
|
10736
11115
|
|
|
11116
|
+
function evaluateAutoHandoffCapabilityLexiconGateReasons(policy = {}, capabilityCoverage = null) {
|
|
11117
|
+
const reasons = [];
|
|
11118
|
+
if (policy.require_capability_lexicon !== true) {
|
|
11119
|
+
return reasons;
|
|
11120
|
+
}
|
|
11121
|
+
|
|
11122
|
+
const coverage = capabilityCoverage && typeof capabilityCoverage === 'object'
|
|
11123
|
+
? capabilityCoverage
|
|
11124
|
+
: null;
|
|
11125
|
+
if (!coverage) {
|
|
11126
|
+
reasons.push('capability lexicon snapshot missing');
|
|
11127
|
+
return reasons;
|
|
11128
|
+
}
|
|
11129
|
+
if (coverage.status === 'error') {
|
|
11130
|
+
reasons.push(`capability lexicon errored: ${coverage.error || 'unknown error'}`);
|
|
11131
|
+
return reasons;
|
|
11132
|
+
}
|
|
11133
|
+
if (coverage.status === 'skipped') {
|
|
11134
|
+
const totalCapabilities = Number(
|
|
11135
|
+
coverage &&
|
|
11136
|
+
coverage.summary &&
|
|
11137
|
+
coverage.summary.total_capabilities !== undefined
|
|
11138
|
+
? coverage.summary.total_capabilities
|
|
11139
|
+
: 0
|
|
11140
|
+
);
|
|
11141
|
+
if (Number.isFinite(totalCapabilities) && totalCapabilities <= 0) {
|
|
11142
|
+
return reasons;
|
|
11143
|
+
}
|
|
11144
|
+
reasons.push(`capability lexicon skipped: ${coverage.reason || 'unknown reason'}`);
|
|
11145
|
+
return reasons;
|
|
11146
|
+
}
|
|
11147
|
+
|
|
11148
|
+
const normalization = coverage.normalization && typeof coverage.normalization === 'object'
|
|
11149
|
+
? coverage.normalization
|
|
11150
|
+
: {};
|
|
11151
|
+
const expectedUnknownCount = Array.isArray(normalization.expected_unknown)
|
|
11152
|
+
? normalization.expected_unknown.length
|
|
11153
|
+
: 0;
|
|
11154
|
+
const providedUnknownCount = Array.isArray(normalization.provided_unknown)
|
|
11155
|
+
? normalization.provided_unknown.length
|
|
11156
|
+
: 0;
|
|
11157
|
+
if (expectedUnknownCount > 0) {
|
|
11158
|
+
reasons.push(`capability_lexicon_expected_unknown_count ${expectedUnknownCount} > allowed 0`);
|
|
11159
|
+
}
|
|
11160
|
+
if (providedUnknownCount > 0) {
|
|
11161
|
+
reasons.push(`capability_lexicon_provided_unknown_count ${providedUnknownCount} > allowed 0`);
|
|
11162
|
+
}
|
|
11163
|
+
|
|
11164
|
+
return reasons;
|
|
11165
|
+
}
|
|
11166
|
+
|
|
10737
11167
|
function evaluateAutoHandoffCapabilitySemanticGateReasons(policy = {}, capabilityCoverage = null) {
|
|
10738
11168
|
const reasons = [];
|
|
10739
11169
|
if (policy.require_capability_semantic !== true) {
|
|
@@ -10854,6 +11284,13 @@ function buildAutoHandoffRunFailureSummary(result = {}) {
|
|
|
10854
11284
|
const releaseGateReasons = releaseGatePreflight && Array.isArray(releaseGatePreflight.reasons)
|
|
10855
11285
|
? releaseGatePreflight.reasons
|
|
10856
11286
|
: [];
|
|
11287
|
+
const moquiBaseline = result && result.moqui_baseline && typeof result.moqui_baseline === 'object'
|
|
11288
|
+
? result.moqui_baseline
|
|
11289
|
+
: null;
|
|
11290
|
+
const moquiCompare = moquiBaseline && moquiBaseline.compare && typeof moquiBaseline.compare === 'object'
|
|
11291
|
+
? moquiBaseline.compare
|
|
11292
|
+
: {};
|
|
11293
|
+
const moquiMatrixRegressions = buildAutoHandoffMoquiCoverageRegressions(moquiCompare);
|
|
10857
11294
|
const highlights = [];
|
|
10858
11295
|
if (typeof result.error === 'string' && result.error.trim()) {
|
|
10859
11296
|
highlights.push(`error: ${result.error.trim()}`);
|
|
@@ -10869,6 +11306,11 @@ function buildAutoHandoffRunFailureSummary(result = {}) {
|
|
|
10869
11306
|
if (failedPhase && failedPhase.id) {
|
|
10870
11307
|
highlights.push(`phase: ${failedPhase.id}${failedPhase.error ? ` (${failedPhase.error})` : ''}`);
|
|
10871
11308
|
}
|
|
11309
|
+
if (moquiMatrixRegressions.length > 0) {
|
|
11310
|
+
highlights.push(
|
|
11311
|
+
`moqui_matrix_regression: ${moquiMatrixRegressions.slice(0, 3).map(item => `${item.label}:${item.delta_rate_percent}%`).join(' | ')}`
|
|
11312
|
+
);
|
|
11313
|
+
}
|
|
10872
11314
|
return {
|
|
10873
11315
|
status: normalizeHandoffText(result && result.status),
|
|
10874
11316
|
failed_phase: failedPhase
|
|
@@ -10880,6 +11322,7 @@ function buildAutoHandoffRunFailureSummary(result = {}) {
|
|
|
10880
11322
|
: null,
|
|
10881
11323
|
gate_failed: gates.passed === false,
|
|
10882
11324
|
gate_reasons: gateReasons,
|
|
11325
|
+
moqui_matrix_regressions: moquiMatrixRegressions,
|
|
10883
11326
|
release_gate_preflight_blocked: Boolean(releaseGatePreflight && releaseGatePreflight.blocked === true),
|
|
10884
11327
|
release_gate_preflight_reasons: releaseGateReasons,
|
|
10885
11328
|
highlights
|
|
@@ -10958,10 +11401,13 @@ function evaluateAutoHandoffRunGates(context = {}) {
|
|
|
10958
11401
|
min_spec_success_rate: 100,
|
|
10959
11402
|
max_risk_level: 'high',
|
|
10960
11403
|
min_ontology_score: 0,
|
|
11404
|
+
max_moqui_matrix_regressions: 0,
|
|
10961
11405
|
max_unmapped_rules: null,
|
|
10962
11406
|
max_undecided_decisions: null,
|
|
10963
11407
|
require_ontology_validation: true,
|
|
10964
|
-
require_scene_package_batch: true
|
|
11408
|
+
require_scene_package_batch: true,
|
|
11409
|
+
require_capability_coverage: true,
|
|
11410
|
+
require_capability_lexicon: true
|
|
10965
11411
|
};
|
|
10966
11412
|
const dryRun = Boolean(context.dryRun);
|
|
10967
11413
|
const specStatus = context.specStatus || {
|
|
@@ -10974,6 +11420,10 @@ function evaluateAutoHandoffRunGates(context = {}) {
|
|
|
10974
11420
|
const moquiBaseline = context.moquiBaseline && typeof context.moquiBaseline === 'object'
|
|
10975
11421
|
? context.moquiBaseline
|
|
10976
11422
|
: null;
|
|
11423
|
+
const moquiCompare = moquiBaseline && moquiBaseline.compare && typeof moquiBaseline.compare === 'object'
|
|
11424
|
+
? moquiBaseline.compare
|
|
11425
|
+
: {};
|
|
11426
|
+
const moquiMatrixRegressions = buildAutoHandoffMoquiCoverageRegressions(moquiCompare);
|
|
10977
11427
|
const scenePackageBatch = context.scenePackageBatch && typeof context.scenePackageBatch === 'object'
|
|
10978
11428
|
? context.scenePackageBatch
|
|
10979
11429
|
: null;
|
|
@@ -11008,6 +11458,7 @@ function evaluateAutoHandoffRunGates(context = {}) {
|
|
|
11008
11458
|
reasons.push(...evaluateAutoHandoffMoquiBaselineGateReasons(policy, moquiBaseline));
|
|
11009
11459
|
reasons.push(...evaluateAutoHandoffScenePackageBatchGateReasons(policy, scenePackageBatch));
|
|
11010
11460
|
reasons.push(...evaluateAutoHandoffCapabilityCoverageGateReasons(policy, capabilityCoverage));
|
|
11461
|
+
reasons.push(...evaluateAutoHandoffCapabilityLexiconGateReasons(policy, capabilityCoverage));
|
|
11011
11462
|
|
|
11012
11463
|
return {
|
|
11013
11464
|
passed: reasons.length === 0,
|
|
@@ -11048,6 +11499,10 @@ function evaluateAutoHandoffRunGates(context = {}) {
|
|
|
11048
11499
|
moquiBaseline.summary &&
|
|
11049
11500
|
moquiBaseline.summary.portfolio_passed === true
|
|
11050
11501
|
),
|
|
11502
|
+
moqui_matrix_regression_count: moquiMatrixRegressions.length,
|
|
11503
|
+
max_moqui_matrix_regressions: Number.isInteger(policy.max_moqui_matrix_regressions)
|
|
11504
|
+
? Number(policy.max_moqui_matrix_regressions)
|
|
11505
|
+
: null,
|
|
11051
11506
|
scene_package_batch_status: normalizeHandoffText(scenePackageBatch && scenePackageBatch.status),
|
|
11052
11507
|
scene_package_batch_passed: Boolean(scenePackageBatch && scenePackageBatch.status === 'passed'),
|
|
11053
11508
|
capability_coverage_status: normalizeHandoffText(capabilityCoverage && capabilityCoverage.status),
|
|
@@ -11055,7 +11510,22 @@ function evaluateAutoHandoffRunGates(context = {}) {
|
|
|
11055
11510
|
Number(capabilityCoverage && capabilityCoverage.summary ? capabilityCoverage.summary.coverage_percent : null)
|
|
11056
11511
|
)
|
|
11057
11512
|
? Number(capabilityCoverage.summary.coverage_percent)
|
|
11058
|
-
: null
|
|
11513
|
+
: null,
|
|
11514
|
+
capability_expected_unknown_count: Array.isArray(
|
|
11515
|
+
capabilityCoverage && capabilityCoverage.normalization
|
|
11516
|
+
? capabilityCoverage.normalization.expected_unknown
|
|
11517
|
+
: null
|
|
11518
|
+
)
|
|
11519
|
+
? capabilityCoverage.normalization.expected_unknown.length
|
|
11520
|
+
: null,
|
|
11521
|
+
capability_provided_unknown_count: Array.isArray(
|
|
11522
|
+
capabilityCoverage && capabilityCoverage.normalization
|
|
11523
|
+
? capabilityCoverage.normalization.provided_unknown
|
|
11524
|
+
: null
|
|
11525
|
+
)
|
|
11526
|
+
? capabilityCoverage.normalization.provided_unknown.length
|
|
11527
|
+
: null,
|
|
11528
|
+
require_capability_lexicon: policy.require_capability_lexicon === true
|
|
11059
11529
|
},
|
|
11060
11530
|
reasons
|
|
11061
11531
|
};
|
|
@@ -11187,6 +11657,10 @@ function buildAutoHandoffRunRecommendations(projectPath, result) {
|
|
|
11187
11657
|
const moquiSummary = moquiBaseline && moquiBaseline.summary && typeof moquiBaseline.summary === 'object'
|
|
11188
11658
|
? moquiBaseline.summary
|
|
11189
11659
|
: null;
|
|
11660
|
+
const moquiCompare = moquiBaseline && moquiBaseline.compare && typeof moquiBaseline.compare === 'object'
|
|
11661
|
+
? moquiBaseline.compare
|
|
11662
|
+
: {};
|
|
11663
|
+
const moquiCoverageRegressions = buildAutoHandoffMoquiCoverageRegressions(moquiCompare);
|
|
11190
11664
|
if (moquiBaseline && moquiBaseline.status === 'error') {
|
|
11191
11665
|
push('sce scene moqui-baseline --json');
|
|
11192
11666
|
} else if (moquiSummary && moquiSummary.portfolio_passed === false) {
|
|
@@ -11199,6 +11673,26 @@ function buildAutoHandoffRunRecommendations(projectPath, result) {
|
|
|
11199
11673
|
'--dry-run --ontology-task-queue-out .kiro/auto/ontology-remediation.lines --json'
|
|
11200
11674
|
);
|
|
11201
11675
|
}
|
|
11676
|
+
if (moquiCoverageRegressions.length > 0) {
|
|
11677
|
+
push(
|
|
11678
|
+
`Recover Moqui matrix regressions before next handoff run: ` +
|
|
11679
|
+
`${moquiCoverageRegressions.slice(0, 3).map(item => `${item.label}:${item.delta_rate_percent}%`).join(' | ')}`
|
|
11680
|
+
);
|
|
11681
|
+
push(
|
|
11682
|
+
'sce scene moqui-baseline --include-all ' +
|
|
11683
|
+
'--compare-with .kiro/reports/release-evidence/moqui-template-baseline.json --json'
|
|
11684
|
+
);
|
|
11685
|
+
if (manifestPath) {
|
|
11686
|
+
push(
|
|
11687
|
+
`sce auto handoff run --manifest ${manifestCli} ` +
|
|
11688
|
+
'--max-moqui-matrix-regressions 0 --json'
|
|
11689
|
+
);
|
|
11690
|
+
push(
|
|
11691
|
+
`sce scene package-publish-batch --manifest ${manifestCli} ` +
|
|
11692
|
+
'--dry-run --ontology-task-queue-out .kiro/auto/ontology-remediation.lines --json'
|
|
11693
|
+
);
|
|
11694
|
+
}
|
|
11695
|
+
}
|
|
11202
11696
|
|
|
11203
11697
|
const scenePackageBatch = result && result.scene_package_batch && typeof result.scene_package_batch === 'object'
|
|
11204
11698
|
? result.scene_package_batch
|
|
@@ -11237,6 +11731,26 @@ function buildAutoHandoffRunRecommendations(projectPath, result) {
|
|
|
11237
11731
|
) {
|
|
11238
11732
|
push('replace deprecated manifest capabilities with canonical Moqui capability ids and rerun `sce auto handoff run --json`');
|
|
11239
11733
|
}
|
|
11734
|
+
if (
|
|
11735
|
+
capabilityNormalization &&
|
|
11736
|
+
Array.isArray(capabilityNormalization.expected_unknown) &&
|
|
11737
|
+
capabilityNormalization.expected_unknown.length > 0
|
|
11738
|
+
) {
|
|
11739
|
+
push(
|
|
11740
|
+
'normalize unknown manifest capabilities and rerun strict gates via ' +
|
|
11741
|
+
'`sce auto handoff capability-matrix --manifest docs/handoffs/handoff-manifest.json --fail-on-gap --json`'
|
|
11742
|
+
);
|
|
11743
|
+
}
|
|
11744
|
+
if (
|
|
11745
|
+
capabilityNormalization &&
|
|
11746
|
+
Array.isArray(capabilityNormalization.provided_unknown) &&
|
|
11747
|
+
capabilityNormalization.provided_unknown.length > 0
|
|
11748
|
+
) {
|
|
11749
|
+
push(
|
|
11750
|
+
'normalize unknown template capabilities via ' +
|
|
11751
|
+
'`node scripts/moqui-lexicon-audit.js --manifest docs/handoffs/handoff-manifest.json --template-dir .kiro/templates/scene-packages --fail-on-gap --json`'
|
|
11752
|
+
);
|
|
11753
|
+
}
|
|
11240
11754
|
|
|
11241
11755
|
return recommendations;
|
|
11242
11756
|
}
|
|
@@ -11340,6 +11854,20 @@ function buildAutoHandoffReleaseEvidenceEntry(projectPath, result, reportFile =
|
|
|
11340
11854
|
const moquiFailedTemplates = moquiCompare && moquiCompare.failed_templates && typeof moquiCompare.failed_templates === 'object'
|
|
11341
11855
|
? moquiCompare.failed_templates
|
|
11342
11856
|
: {};
|
|
11857
|
+
const moquiScopeBreakdown = moquiSummary && moquiSummary.scope_breakdown && typeof moquiSummary.scope_breakdown === 'object'
|
|
11858
|
+
? moquiSummary.scope_breakdown
|
|
11859
|
+
: {};
|
|
11860
|
+
const moquiCoverageMatrix = moquiSummary && moquiSummary.coverage_matrix && typeof moquiSummary.coverage_matrix === 'object'
|
|
11861
|
+
? moquiSummary.coverage_matrix
|
|
11862
|
+
: {};
|
|
11863
|
+
const moquiCoverageMatrixDeltas = moquiCompare && moquiCompare.coverage_matrix_deltas
|
|
11864
|
+
&& typeof moquiCompare.coverage_matrix_deltas === 'object'
|
|
11865
|
+
? moquiCompare.coverage_matrix_deltas
|
|
11866
|
+
: {};
|
|
11867
|
+
const moquiCoverageMatrixRegressions = buildAutoHandoffMoquiCoverageRegressions(moquiCompare);
|
|
11868
|
+
const moquiGapFrequency = Array.isArray(moquiSummary && moquiSummary.gap_frequency)
|
|
11869
|
+
? moquiSummary.gap_frequency
|
|
11870
|
+
: [];
|
|
11343
11871
|
const scenePackageBatch = result && result.scene_package_batch && typeof result.scene_package_batch === 'object'
|
|
11344
11872
|
? result.scene_package_batch
|
|
11345
11873
|
: {};
|
|
@@ -11394,7 +11922,9 @@ function buildAutoHandoffReleaseEvidenceEntry(projectPath, result, reportFile =
|
|
|
11394
11922
|
risk_level: normalizeHandoffText(gateActual.risk_level),
|
|
11395
11923
|
ontology_quality_score: toNumber(gateActual.ontology_quality_score),
|
|
11396
11924
|
ontology_business_rule_unmapped: toNumber(gateActual.ontology_business_rule_unmapped),
|
|
11397
|
-
ontology_decision_undecided: toNumber(gateActual.ontology_decision_undecided)
|
|
11925
|
+
ontology_decision_undecided: toNumber(gateActual.ontology_decision_undecided),
|
|
11926
|
+
capability_expected_unknown_count: toNumber(gateActual.capability_expected_unknown_count),
|
|
11927
|
+
capability_provided_unknown_count: toNumber(gateActual.capability_provided_unknown_count)
|
|
11398
11928
|
}
|
|
11399
11929
|
},
|
|
11400
11930
|
release_gate_preflight: result && result.release_gate_preflight && typeof result.release_gate_preflight === 'object'
|
|
@@ -11443,7 +11973,14 @@ function buildAutoHandoffReleaseEvidenceEntry(projectPath, result, reportFile =
|
|
|
11443
11973
|
valid_rate_percent: toNumber(moquiSummary.valid_rate_percent),
|
|
11444
11974
|
baseline_passed: toNumber(moquiSummary.baseline_passed),
|
|
11445
11975
|
baseline_failed: toNumber(moquiSummary.baseline_failed),
|
|
11446
|
-
portfolio_passed: moquiSummary.portfolio_passed === true
|
|
11976
|
+
portfolio_passed: moquiSummary.portfolio_passed === true,
|
|
11977
|
+
scope_breakdown: {
|
|
11978
|
+
moqui_erp: toNumber(moquiScopeBreakdown.moqui_erp),
|
|
11979
|
+
scene_orchestration: toNumber(moquiScopeBreakdown.scene_orchestration),
|
|
11980
|
+
other: toNumber(moquiScopeBreakdown.other)
|
|
11981
|
+
},
|
|
11982
|
+
coverage_matrix: moquiCoverageMatrix,
|
|
11983
|
+
gap_frequency: moquiGapFrequency
|
|
11447
11984
|
},
|
|
11448
11985
|
compare: Object.keys(moquiCompare).length === 0
|
|
11449
11986
|
? null
|
|
@@ -11457,6 +11994,8 @@ function buildAutoHandoffReleaseEvidenceEntry(projectPath, result, reportFile =
|
|
|
11457
11994
|
baseline_passed: toNumber(moquiDeltas.baseline_passed),
|
|
11458
11995
|
baseline_failed: toNumber(moquiDeltas.baseline_failed)
|
|
11459
11996
|
},
|
|
11997
|
+
coverage_matrix_deltas: moquiCoverageMatrixDeltas,
|
|
11998
|
+
coverage_matrix_regressions: moquiCoverageMatrixRegressions,
|
|
11460
11999
|
failed_templates: {
|
|
11461
12000
|
newly_failed: Array.isArray(moquiFailedTemplates.newly_failed) ? moquiFailedTemplates.newly_failed : [],
|
|
11462
12001
|
recovered: Array.isArray(moquiFailedTemplates.recovered) ? moquiFailedTemplates.recovered : []
|
|
@@ -11536,6 +12075,16 @@ function buildAutoHandoffReleaseEvidenceEntry(projectPath, result, reportFile =
|
|
|
11536
12075
|
},
|
|
11537
12076
|
continued_from: result && result.continued_from ? result.continued_from : null,
|
|
11538
12077
|
policy: {
|
|
12078
|
+
max_moqui_matrix_regressions: Number.isFinite(
|
|
12079
|
+
Number(result && result.policy ? result.policy.max_moqui_matrix_regressions : null)
|
|
12080
|
+
)
|
|
12081
|
+
? Number(result.policy.max_moqui_matrix_regressions)
|
|
12082
|
+
: null,
|
|
12083
|
+
require_capability_lexicon: Boolean(
|
|
12084
|
+
result &&
|
|
12085
|
+
result.policy &&
|
|
12086
|
+
result.policy.require_capability_lexicon === true
|
|
12087
|
+
),
|
|
11539
12088
|
require_release_gate_preflight: Boolean(
|
|
11540
12089
|
result &&
|
|
11541
12090
|
result.policy &&
|
|
@@ -11671,6 +12220,17 @@ async function writeAutoHandoffRunReport(projectPath, result, outCandidate = nul
|
|
|
11671
12220
|
function buildAutoHandoffMoquiBaselinePhaseDetails(payload) {
|
|
11672
12221
|
const baseline = payload && typeof payload === 'object' ? payload : {};
|
|
11673
12222
|
const summary = baseline.summary && typeof baseline.summary === 'object' ? baseline.summary : null;
|
|
12223
|
+
const compare = baseline.compare && typeof baseline.compare === 'object' ? baseline.compare : {};
|
|
12224
|
+
const regressions = buildAutoHandoffMoquiCoverageRegressions(compare);
|
|
12225
|
+
const scopeBreakdown = summary && summary.scope_breakdown && typeof summary.scope_breakdown === 'object'
|
|
12226
|
+
? summary.scope_breakdown
|
|
12227
|
+
: null;
|
|
12228
|
+
const coverageMatrix = summary && summary.coverage_matrix && typeof summary.coverage_matrix === 'object'
|
|
12229
|
+
? summary.coverage_matrix
|
|
12230
|
+
: null;
|
|
12231
|
+
const gapFrequency = summary && Array.isArray(summary.gap_frequency)
|
|
12232
|
+
? summary.gap_frequency
|
|
12233
|
+
: [];
|
|
11674
12234
|
return {
|
|
11675
12235
|
status: baseline.status || 'unknown',
|
|
11676
12236
|
generated: baseline.generated === true,
|
|
@@ -11681,7 +12241,20 @@ function buildAutoHandoffMoquiBaselinePhaseDetails(payload) {
|
|
|
11681
12241
|
: null,
|
|
11682
12242
|
valid_rate_percent: summary && Number.isFinite(Number(summary.valid_rate_percent))
|
|
11683
12243
|
? Number(summary.valid_rate_percent)
|
|
11684
|
-
: null
|
|
12244
|
+
: null,
|
|
12245
|
+
scope_breakdown: scopeBreakdown,
|
|
12246
|
+
coverage_matrix: coverageMatrix,
|
|
12247
|
+
gap_frequency_top: gapFrequency.slice(0, 5),
|
|
12248
|
+
entity_coverage_rate_percent: getAutoHandoffMoquiCoverageMetric(summary, 'entity_coverage', 'rate_percent'),
|
|
12249
|
+
relation_coverage_rate_percent: getAutoHandoffMoquiCoverageMetric(summary, 'relation_coverage', 'rate_percent'),
|
|
12250
|
+
business_rule_closed_rate_percent: getAutoHandoffMoquiCoverageMetric(summary, 'business_rule_closed', 'rate_percent'),
|
|
12251
|
+
decision_closed_rate_percent: getAutoHandoffMoquiCoverageMetric(summary, 'decision_closed', 'rate_percent'),
|
|
12252
|
+
coverage_matrix_deltas: getAutoHandoffMoquiCoverageDeltaMatrix(compare),
|
|
12253
|
+
coverage_matrix_regressions: regressions,
|
|
12254
|
+
entity_coverage_delta_rate_percent: getAutoHandoffMoquiCoverageDeltaMetric(compare, 'entity_coverage', 'rate_percent'),
|
|
12255
|
+
business_rule_closed_delta_rate_percent: getAutoHandoffMoquiCoverageDeltaMetric(compare, 'business_rule_closed', 'rate_percent'),
|
|
12256
|
+
decision_closed_delta_rate_percent: getAutoHandoffMoquiCoverageDeltaMetric(compare, 'decision_closed', 'rate_percent'),
|
|
12257
|
+
matrix_regression_count: regressions.length
|
|
11685
12258
|
};
|
|
11686
12259
|
}
|
|
11687
12260
|
|
|
@@ -11778,6 +12351,15 @@ async function buildAutoHandoffMoquiBaselineSnapshot(projectPath) {
|
|
|
11778
12351
|
const failedTemplates = compare && compare.failed_templates && typeof compare.failed_templates === 'object'
|
|
11779
12352
|
? compare.failed_templates
|
|
11780
12353
|
: {};
|
|
12354
|
+
const scopeBreakdown = summary && summary.scope_breakdown && typeof summary.scope_breakdown === 'object'
|
|
12355
|
+
? summary.scope_breakdown
|
|
12356
|
+
: {};
|
|
12357
|
+
const coverageMatrix = summary && summary.coverage_matrix && typeof summary.coverage_matrix === 'object'
|
|
12358
|
+
? summary.coverage_matrix
|
|
12359
|
+
: {};
|
|
12360
|
+
const gapFrequency = summary && Array.isArray(summary.gap_frequency)
|
|
12361
|
+
? summary.gap_frequency
|
|
12362
|
+
: [];
|
|
11781
12363
|
|
|
11782
12364
|
return {
|
|
11783
12365
|
status: summary.portfolio_passed === true ? 'passed' : 'failed',
|
|
@@ -11789,13 +12371,22 @@ async function buildAutoHandoffMoquiBaselineSnapshot(projectPath) {
|
|
|
11789
12371
|
valid_rate_percent: Number.isFinite(Number(summary.valid_rate_percent)) ? Number(summary.valid_rate_percent) : null,
|
|
11790
12372
|
baseline_passed: Number(summary.baseline_passed) || 0,
|
|
11791
12373
|
baseline_failed: Number(summary.baseline_failed) || 0,
|
|
11792
|
-
portfolio_passed: summary.portfolio_passed === true
|
|
12374
|
+
portfolio_passed: summary.portfolio_passed === true,
|
|
12375
|
+
scope_breakdown: {
|
|
12376
|
+
moqui_erp: Number(scopeBreakdown.moqui_erp) || 0,
|
|
12377
|
+
scene_orchestration: Number(scopeBreakdown.scene_orchestration) || 0,
|
|
12378
|
+
other: Number(scopeBreakdown.other) || 0
|
|
12379
|
+
},
|
|
12380
|
+
coverage_matrix: coverageMatrix,
|
|
12381
|
+
gap_frequency: gapFrequency
|
|
11793
12382
|
},
|
|
11794
12383
|
compare: compare
|
|
11795
12384
|
? {
|
|
11796
12385
|
previous_generated_at: compare.previous_generated_at || null,
|
|
11797
12386
|
previous_template_root: compare.previous_template_root || null,
|
|
11798
12387
|
deltas: compare.deltas || null,
|
|
12388
|
+
coverage_matrix_deltas: compare.coverage_matrix_deltas || null,
|
|
12389
|
+
coverage_matrix_regressions: buildAutoHandoffMoquiCoverageRegressions(compare),
|
|
11799
12390
|
failed_templates: {
|
|
11800
12391
|
previous: Array.isArray(failedTemplates.previous) ? failedTemplates.previous : [],
|
|
11801
12392
|
current: Array.isArray(failedTemplates.current) ? failedTemplates.current : [],
|
|
@@ -12604,9 +13195,23 @@ function buildAutoHandoffCapabilityMatrixRecommendations(result = {}) {
|
|
|
12604
13195
|
const coverageSummary = capabilityCoverage && capabilityCoverage.summary && typeof capabilityCoverage.summary === 'object'
|
|
12605
13196
|
? capabilityCoverage.summary
|
|
12606
13197
|
: {};
|
|
13198
|
+
const coverageNormalization = capabilityCoverage && capabilityCoverage.normalization &&
|
|
13199
|
+
typeof capabilityCoverage.normalization === 'object'
|
|
13200
|
+
? capabilityCoverage.normalization
|
|
13201
|
+
: {};
|
|
13202
|
+
const expectedUnknownCount = Array.isArray(coverageNormalization.expected_unknown)
|
|
13203
|
+
? coverageNormalization.expected_unknown.length
|
|
13204
|
+
: 0;
|
|
13205
|
+
const providedUnknownCount = Array.isArray(coverageNormalization.provided_unknown)
|
|
13206
|
+
? coverageNormalization.provided_unknown.length
|
|
13207
|
+
: 0;
|
|
12607
13208
|
const baseline = result && result.moqui_baseline && typeof result.moqui_baseline === 'object'
|
|
12608
13209
|
? result.moqui_baseline
|
|
12609
13210
|
: {};
|
|
13211
|
+
const baselineCompare = baseline && baseline.compare && typeof baseline.compare === 'object'
|
|
13212
|
+
? baseline.compare
|
|
13213
|
+
: {};
|
|
13214
|
+
const baselineRegressions = buildAutoHandoffMoquiCoverageRegressions(baselineCompare);
|
|
12610
13215
|
|
|
12611
13216
|
if (templateDiff.compatibility === 'needs-sync') {
|
|
12612
13217
|
push(`Sync template library and rerun: sce auto handoff template-diff --manifest ${manifestCli} --json`);
|
|
@@ -12614,6 +13219,12 @@ function buildAutoHandoffCapabilityMatrixRecommendations(result = {}) {
|
|
|
12614
13219
|
if (baseline.status === 'error' || (baseline.summary && baseline.summary.portfolio_passed === false)) {
|
|
12615
13220
|
push('Rebuild Moqui baseline: sce scene moqui-baseline --json');
|
|
12616
13221
|
}
|
|
13222
|
+
if (baselineRegressions.length > 0) {
|
|
13223
|
+
push(
|
|
13224
|
+
`Recover Moqui matrix regressions: ` +
|
|
13225
|
+
`${baselineRegressions.slice(0, 3).map(item => `${item.label}:${item.delta_rate_percent}%`).join(' | ')}`
|
|
13226
|
+
);
|
|
13227
|
+
}
|
|
12617
13228
|
if (capabilityCoverage.status === 'skipped') {
|
|
12618
13229
|
push('Declare `capabilities` in handoff manifest to enable capability matrix coverage gates.');
|
|
12619
13230
|
}
|
|
@@ -12629,6 +13240,13 @@ function buildAutoHandoffCapabilityMatrixRecommendations(result = {}) {
|
|
|
12629
13240
|
`sce scene package-ontology-backfill-batch --manifest ${manifestCli} --json`
|
|
12630
13241
|
);
|
|
12631
13242
|
}
|
|
13243
|
+
if (expectedUnknownCount > 0 || providedUnknownCount > 0) {
|
|
13244
|
+
push(
|
|
13245
|
+
`Normalize capability lexicon gaps with strict audit: ` +
|
|
13246
|
+
`node scripts/moqui-lexicon-audit.js --manifest ${manifestCli} ` +
|
|
13247
|
+
'--template-dir .kiro/templates/scene-packages --fail-on-gap --json'
|
|
13248
|
+
);
|
|
13249
|
+
}
|
|
12632
13250
|
if (result.remediation_queue && result.remediation_queue.file) {
|
|
12633
13251
|
push(
|
|
12634
13252
|
`Replay remediation queue: sce auto close-loop-batch ${quoteCliArg(result.remediation_queue.file)} --format lines --json`
|
|
@@ -12660,12 +13278,31 @@ function renderAutoHandoffCapabilityMatrixMarkdown(payload = {}) {
|
|
|
12660
13278
|
const baselineSummary = moquiBaseline && moquiBaseline.summary && typeof moquiBaseline.summary === 'object'
|
|
12661
13279
|
? moquiBaseline.summary
|
|
12662
13280
|
: {};
|
|
13281
|
+
const baselineCompare = moquiBaseline && moquiBaseline.compare && typeof moquiBaseline.compare === 'object'
|
|
13282
|
+
? moquiBaseline.compare
|
|
13283
|
+
: {};
|
|
13284
|
+
const baselineScopeBreakdown = baselineSummary && baselineSummary.scope_breakdown && typeof baselineSummary.scope_breakdown === 'object'
|
|
13285
|
+
? baselineSummary.scope_breakdown
|
|
13286
|
+
: {};
|
|
13287
|
+
const baselineGapFrequency = Array.isArray(baselineSummary && baselineSummary.gap_frequency)
|
|
13288
|
+
? baselineSummary.gap_frequency
|
|
13289
|
+
: [];
|
|
12663
13290
|
const capabilityCoverage = payload && payload.capability_coverage && typeof payload.capability_coverage === 'object'
|
|
12664
13291
|
? payload.capability_coverage
|
|
12665
13292
|
: {};
|
|
12666
13293
|
const coverageSummary = capabilityCoverage && capabilityCoverage.summary && typeof capabilityCoverage.summary === 'object'
|
|
12667
13294
|
? capabilityCoverage.summary
|
|
12668
13295
|
: {};
|
|
13296
|
+
const coverageNormalization = capabilityCoverage && capabilityCoverage.normalization &&
|
|
13297
|
+
typeof capabilityCoverage.normalization === 'object'
|
|
13298
|
+
? capabilityCoverage.normalization
|
|
13299
|
+
: {};
|
|
13300
|
+
const expectedUnknownCount = Array.isArray(coverageNormalization.expected_unknown)
|
|
13301
|
+
? coverageNormalization.expected_unknown.length
|
|
13302
|
+
: 0;
|
|
13303
|
+
const providedUnknownCount = Array.isArray(coverageNormalization.provided_unknown)
|
|
13304
|
+
? coverageNormalization.provided_unknown.length
|
|
13305
|
+
: 0;
|
|
12669
13306
|
const coverage = Array.isArray(capabilityCoverage && capabilityCoverage.coverage)
|
|
12670
13307
|
? capabilityCoverage.coverage
|
|
12671
13308
|
: [];
|
|
@@ -12685,6 +13322,7 @@ function renderAutoHandoffCapabilityMatrixMarkdown(payload = {}) {
|
|
|
12685
13322
|
`- Capabilities: ${handoff.capability_count !== undefined ? handoff.capability_count : 'n/a'}`,
|
|
12686
13323
|
`- Min capability coverage: ${policy.min_capability_coverage_percent !== undefined ? `${policy.min_capability_coverage_percent}%` : 'n/a'}`,
|
|
12687
13324
|
`- Min capability semantic completeness: ${policy.min_capability_semantic_percent !== undefined ? `${policy.min_capability_semantic_percent}%` : 'n/a'}`,
|
|
13325
|
+
`- Capability lexicon gate: ${policy.require_capability_lexicon === false ? 'disabled' : 'enabled'}`,
|
|
12688
13326
|
'',
|
|
12689
13327
|
'## Gates',
|
|
12690
13328
|
'',
|
|
@@ -12703,6 +13341,18 @@ function renderAutoHandoffCapabilityMatrixMarkdown(payload = {}) {
|
|
|
12703
13341
|
`- Portfolio passed: ${baselineSummary.portfolio_passed === true ? 'yes' : (baselineSummary.portfolio_passed === false ? 'no' : 'n/a')}`,
|
|
12704
13342
|
`- Avg score: ${formatAutoHandoffRegressionValue(baselineSummary.avg_score)}`,
|
|
12705
13343
|
`- Valid-rate: ${formatAutoHandoffRegressionValue(baselineSummary.valid_rate_percent)}%`,
|
|
13344
|
+
`- Scope mix (moqui/suite/other): ${formatAutoHandoffRegressionValue(baselineScopeBreakdown.moqui_erp, '0')}/${formatAutoHandoffRegressionValue(baselineScopeBreakdown.scene_orchestration, '0')}/${formatAutoHandoffRegressionValue(baselineScopeBreakdown.other, '0')}`,
|
|
13345
|
+
`- Entity coverage: ${formatAutoHandoffMoquiCoverageMetric(baselineSummary, 'entity_coverage', 'rate_percent', '%')}`,
|
|
13346
|
+
`- Relation coverage: ${formatAutoHandoffMoquiCoverageMetric(baselineSummary, 'relation_coverage', 'rate_percent', '%')}`,
|
|
13347
|
+
`- Business-rule coverage: ${formatAutoHandoffMoquiCoverageMetric(baselineSummary, 'business_rule_coverage', 'rate_percent', '%')}`,
|
|
13348
|
+
`- Business-rule closed: ${formatAutoHandoffMoquiCoverageMetric(baselineSummary, 'business_rule_closed', 'rate_percent', '%')}`,
|
|
13349
|
+
`- Decision coverage: ${formatAutoHandoffMoquiCoverageMetric(baselineSummary, 'decision_coverage', 'rate_percent', '%')}`,
|
|
13350
|
+
`- Decision closed: ${formatAutoHandoffMoquiCoverageMetric(baselineSummary, 'decision_closed', 'rate_percent', '%')}`,
|
|
13351
|
+
`- Entity coverage delta: ${formatAutoHandoffMoquiCoverageDeltaMetric(baselineCompare, 'entity_coverage', 'rate_percent', '%')}`,
|
|
13352
|
+
`- Business-rule closed delta: ${formatAutoHandoffMoquiCoverageDeltaMetric(baselineCompare, 'business_rule_closed', 'rate_percent', '%')}`,
|
|
13353
|
+
`- Decision closed delta: ${formatAutoHandoffMoquiCoverageDeltaMetric(baselineCompare, 'decision_closed', 'rate_percent', '%')}`,
|
|
13354
|
+
`- Matrix regressions: ${formatAutoHandoffMoquiCoverageRegressions(baselineCompare, 5)}`,
|
|
13355
|
+
`- Top baseline gaps: ${baselineGapFrequency.length > 0 ? baselineGapFrequency.slice(0, 3).map(item => `${item.gap}:${item.count}`).join(' | ') : 'none'}`,
|
|
12706
13356
|
'',
|
|
12707
13357
|
'## Capability Coverage',
|
|
12708
13358
|
'',
|
|
@@ -12713,6 +13363,8 @@ function renderAutoHandoffCapabilityMatrixMarkdown(payload = {}) {
|
|
|
12713
13363
|
`- Uncovered capabilities: ${formatAutoHandoffRegressionValue(coverageSummary.uncovered_capabilities, '0')}`,
|
|
12714
13364
|
`- Semantic complete: ${formatAutoHandoffRegressionValue(coverageSummary.semantic_complete_percent)}%`,
|
|
12715
13365
|
`- Semantic passed: ${coverageSummary.semantic_passed === true ? 'yes' : (coverageSummary.semantic_passed === false ? 'no' : 'n/a')}`,
|
|
13366
|
+
`- Expected unknown capability aliases: ${expectedUnknownCount}`,
|
|
13367
|
+
`- Provided unknown capability aliases: ${providedUnknownCount}`,
|
|
12716
13368
|
'',
|
|
12717
13369
|
'| Capability | Covered | Semantic Complete | Missing Semantic Dimensions | Matched Templates |',
|
|
12718
13370
|
'| --- | --- | --- | --- | --- |'
|
|
@@ -12767,6 +13419,7 @@ async function buildAutoHandoffCapabilityMatrix(projectPath, options = {}) {
|
|
|
12767
13419
|
min_capability_semantic_percent: normalizeHandoffMinCapabilitySemantic(options.minCapabilitySemantic),
|
|
12768
13420
|
require_capability_coverage: true,
|
|
12769
13421
|
require_capability_semantic: options.requireCapabilitySemantic !== false,
|
|
13422
|
+
require_capability_lexicon: options.requireCapabilityLexicon !== false,
|
|
12770
13423
|
require_moqui_baseline: true
|
|
12771
13424
|
};
|
|
12772
13425
|
|
|
@@ -12791,11 +13444,16 @@ async function buildAutoHandoffCapabilityMatrix(projectPath, options = {}) {
|
|
|
12791
13444
|
policy,
|
|
12792
13445
|
capabilityCoverage
|
|
12793
13446
|
);
|
|
13447
|
+
const lexiconGateReasons = evaluateAutoHandoffCapabilityLexiconGateReasons(
|
|
13448
|
+
policy,
|
|
13449
|
+
capabilityCoverage
|
|
13450
|
+
);
|
|
12794
13451
|
const reasons = [
|
|
12795
13452
|
...templateSyncReasons,
|
|
12796
13453
|
...baselineGateReasons.map(item => `moqui-baseline:${item}`),
|
|
12797
13454
|
...capabilityGateReasons.map(item => `capability-coverage:${item}`),
|
|
12798
|
-
...semanticGateReasons.map(item => `capability-semantic:${item}`)
|
|
13455
|
+
...semanticGateReasons.map(item => `capability-semantic:${item}`),
|
|
13456
|
+
...lexiconGateReasons.map(item => `capability-lexicon:${item}`)
|
|
12799
13457
|
];
|
|
12800
13458
|
|
|
12801
13459
|
const result = {
|
|
@@ -12840,6 +13498,10 @@ async function buildAutoHandoffCapabilityMatrix(projectPath, options = {}) {
|
|
|
12840
13498
|
capability_semantic: {
|
|
12841
13499
|
passed: semanticGateReasons.length === 0,
|
|
12842
13500
|
reasons: semanticGateReasons
|
|
13501
|
+
},
|
|
13502
|
+
capability_lexicon: {
|
|
13503
|
+
passed: lexiconGateReasons.length === 0,
|
|
13504
|
+
reasons: lexiconGateReasons
|
|
12843
13505
|
}
|
|
12844
13506
|
},
|
|
12845
13507
|
remediation_queue: null,
|
|
@@ -12880,6 +13542,7 @@ function collectAutoHandoffMoquiRemediationGoals(result) {
|
|
|
12880
13542
|
const baselineCompare = moquiBaseline && moquiBaseline.compare && typeof moquiBaseline.compare === 'object'
|
|
12881
13543
|
? moquiBaseline.compare
|
|
12882
13544
|
: null;
|
|
13545
|
+
const baselineRegressions = buildAutoHandoffMoquiCoverageRegressions(baselineCompare || {});
|
|
12883
13546
|
const baselineFailedTemplates = baselineCompare && baselineCompare.failed_templates && typeof baselineCompare.failed_templates === 'object'
|
|
12884
13547
|
? baselineCompare.failed_templates
|
|
12885
13548
|
: {};
|
|
@@ -12898,6 +13561,22 @@ function collectAutoHandoffMoquiRemediationGoals(result) {
|
|
|
12898
13561
|
pushGoal(`remediate moqui template ${templateId} ontology semantics and close baseline gaps`);
|
|
12899
13562
|
}
|
|
12900
13563
|
}
|
|
13564
|
+
if (baselineRegressions.length > 0) {
|
|
13565
|
+
for (const item of baselineRegressions.slice(0, 5)) {
|
|
13566
|
+
pushGoal(
|
|
13567
|
+
`recover moqui matrix regression ${item.label} (${item.delta_rate_percent}%) by closing ontology semantic gaps`
|
|
13568
|
+
);
|
|
13569
|
+
if (item.metric === 'business_rule_closed') {
|
|
13570
|
+
pushGoal('remap governance_contract.business_rules for Moqui templates until closure regression is recovered');
|
|
13571
|
+
}
|
|
13572
|
+
if (item.metric === 'decision_closed') {
|
|
13573
|
+
pushGoal('resolve undecided governance_contract.decision_logic entries in Moqui templates');
|
|
13574
|
+
}
|
|
13575
|
+
if (item.metric === 'entity_coverage' || item.metric === 'relation_coverage') {
|
|
13576
|
+
pushGoal('backfill ontology_model entities/relations for regressed Moqui templates');
|
|
13577
|
+
}
|
|
13578
|
+
}
|
|
13579
|
+
}
|
|
12901
13580
|
|
|
12902
13581
|
const scenePackageBatch = result && result.scene_package_batch && typeof result.scene_package_batch === 'object'
|
|
12903
13582
|
? result.scene_package_batch
|
|
@@ -13007,6 +13686,16 @@ function collectAutoHandoffMoquiRemediationGoals(result) {
|
|
|
13007
13686
|
pushGoal(`align unknown manifest capability ${raw} with Moqui capability lexicon`);
|
|
13008
13687
|
}
|
|
13009
13688
|
}
|
|
13689
|
+
if (
|
|
13690
|
+
capabilityNormalization &&
|
|
13691
|
+
Array.isArray(capabilityNormalization.provided_unknown) &&
|
|
13692
|
+
capabilityNormalization.provided_unknown.length > 0
|
|
13693
|
+
) {
|
|
13694
|
+
for (const item of capabilityNormalization.provided_unknown) {
|
|
13695
|
+
const raw = item && item.raw ? item.raw : '(unknown)';
|
|
13696
|
+
pushGoal(`align unknown template capability ${raw} with Moqui capability lexicon`);
|
|
13697
|
+
}
|
|
13698
|
+
}
|
|
13010
13699
|
|
|
13011
13700
|
return goals;
|
|
13012
13701
|
}
|
|
@@ -13229,6 +13918,13 @@ async function runAutoHandoff(projectPath, options = {}) {
|
|
|
13229
13918
|
if (capabilityCoverageGateReasons.length > 0) {
|
|
13230
13919
|
throw new Error(`handoff capability coverage gate failed: ${capabilityCoverageGateReasons.join('; ')}`);
|
|
13231
13920
|
}
|
|
13921
|
+
const capabilityLexiconGateReasons = evaluateAutoHandoffCapabilityLexiconGateReasons(
|
|
13922
|
+
result.policy,
|
|
13923
|
+
result.moqui_capability_coverage
|
|
13924
|
+
);
|
|
13925
|
+
if (capabilityLexiconGateReasons.length > 0) {
|
|
13926
|
+
throw new Error(`handoff capability lexicon gate failed: ${capabilityLexiconGateReasons.join('; ')}`);
|
|
13927
|
+
}
|
|
13232
13928
|
} catch (capabilityCoverageError) {
|
|
13233
13929
|
failAutoHandoffRunPhase(capabilityCoveragePhase, capabilityCoverageError);
|
|
13234
13930
|
if (!result.moqui_capability_coverage) {
|
|
@@ -14550,6 +15246,18 @@ function normalizeGovernanceHandoffQualitySnapshot(snapshotCandidate) {
|
|
|
14550
15246
|
latest_ontology_quality_score: toGovernanceReleaseGateNumber(snapshotCandidate.latest_ontology_quality_score),
|
|
14551
15247
|
latest_capability_coverage_percent: toGovernanceReleaseGateNumber(snapshotCandidate.latest_capability_coverage_percent),
|
|
14552
15248
|
latest_capability_coverage_passed: parseAutoHandoffGateBoolean(snapshotCandidate.latest_capability_coverage_passed, null),
|
|
15249
|
+
latest_capability_expected_unknown_count: toGovernanceReleaseGateNumber(
|
|
15250
|
+
snapshotCandidate.latest_capability_expected_unknown_count
|
|
15251
|
+
),
|
|
15252
|
+
latest_capability_provided_unknown_count: toGovernanceReleaseGateNumber(
|
|
15253
|
+
snapshotCandidate.latest_capability_provided_unknown_count
|
|
15254
|
+
),
|
|
15255
|
+
latest_moqui_matrix_regression_count: toGovernanceReleaseGateNumber(
|
|
15256
|
+
snapshotCandidate.latest_moqui_matrix_regression_count
|
|
15257
|
+
),
|
|
15258
|
+
latest_moqui_matrix_regression_gate_max: toGovernanceReleaseGateNumber(
|
|
15259
|
+
snapshotCandidate.latest_moqui_matrix_regression_gate_max
|
|
15260
|
+
),
|
|
14553
15261
|
latest_release_gate_preflight_blocked: parseAutoHandoffGateBoolean(
|
|
14554
15262
|
snapshotCandidate.latest_release_gate_preflight_blocked,
|
|
14555
15263
|
null
|
|
@@ -14558,6 +15266,21 @@ function normalizeGovernanceHandoffQualitySnapshot(snapshotCandidate) {
|
|
|
14558
15266
|
gate_pass_rate_percent: toGovernanceReleaseGateNumber(snapshotCandidate.gate_pass_rate_percent),
|
|
14559
15267
|
capability_coverage_pass_rate_percent: toGovernanceReleaseGateNumber(
|
|
14560
15268
|
snapshotCandidate.capability_coverage_pass_rate_percent
|
|
15269
|
+
),
|
|
15270
|
+
capability_expected_unknown_positive_rate_percent: toGovernanceReleaseGateNumber(
|
|
15271
|
+
snapshotCandidate.capability_expected_unknown_positive_rate_percent
|
|
15272
|
+
),
|
|
15273
|
+
capability_provided_unknown_positive_rate_percent: toGovernanceReleaseGateNumber(
|
|
15274
|
+
snapshotCandidate.capability_provided_unknown_positive_rate_percent
|
|
15275
|
+
),
|
|
15276
|
+
avg_moqui_matrix_regression_count: toGovernanceReleaseGateNumber(
|
|
15277
|
+
snapshotCandidate.avg_moqui_matrix_regression_count
|
|
15278
|
+
),
|
|
15279
|
+
max_moqui_matrix_regression_count: toGovernanceReleaseGateNumber(
|
|
15280
|
+
snapshotCandidate.max_moqui_matrix_regression_count
|
|
15281
|
+
),
|
|
15282
|
+
moqui_matrix_regression_positive_rate_percent: toGovernanceReleaseGateNumber(
|
|
15283
|
+
snapshotCandidate.moqui_matrix_regression_positive_rate_percent
|
|
14561
15284
|
)
|
|
14562
15285
|
};
|
|
14563
15286
|
}
|
|
@@ -17226,6 +17949,10 @@ async function loadGovernanceHandoffQualitySignals(projectPath) {
|
|
|
17226
17949
|
latest_ontology_quality_score: null,
|
|
17227
17950
|
latest_capability_coverage_percent: null,
|
|
17228
17951
|
latest_capability_coverage_passed: null,
|
|
17952
|
+
latest_capability_expected_unknown_count: null,
|
|
17953
|
+
latest_capability_provided_unknown_count: null,
|
|
17954
|
+
latest_moqui_matrix_regression_count: null,
|
|
17955
|
+
latest_moqui_matrix_regression_gate_max: null,
|
|
17229
17956
|
latest_scene_package_batch_passed: null,
|
|
17230
17957
|
latest_release_gate_preflight_blocked: null,
|
|
17231
17958
|
latest_failure_highlights: [],
|
|
@@ -17234,6 +17961,11 @@ async function loadGovernanceHandoffQualitySignals(projectPath) {
|
|
|
17234
17961
|
capability_coverage_pass_rate_percent: null,
|
|
17235
17962
|
scene_package_batch_pass_rate_percent: null,
|
|
17236
17963
|
avg_ontology_quality_score: null,
|
|
17964
|
+
capability_expected_unknown_positive_rate_percent: null,
|
|
17965
|
+
capability_provided_unknown_positive_rate_percent: null,
|
|
17966
|
+
avg_moqui_matrix_regression_count: null,
|
|
17967
|
+
max_moqui_matrix_regression_count: null,
|
|
17968
|
+
moqui_matrix_regression_positive_rate_percent: null,
|
|
17237
17969
|
parse_error: null
|
|
17238
17970
|
};
|
|
17239
17971
|
if (!(await fs.pathExists(evidenceFile))) {
|
|
@@ -17298,6 +18030,101 @@ async function loadGovernanceHandoffQualitySignals(projectPath) {
|
|
|
17298
18030
|
const latestFailureHighlights = Array.isArray(latestFailureSummary.highlights)
|
|
17299
18031
|
? latestFailureSummary.highlights.map(item => `${item || ''}`.trim()).filter(Boolean).slice(0, 5)
|
|
17300
18032
|
: [];
|
|
18033
|
+
const deriveMoquiMatrixRegressionCount = entry => {
|
|
18034
|
+
if (!entry || typeof entry !== 'object') {
|
|
18035
|
+
return null;
|
|
18036
|
+
}
|
|
18037
|
+
const gate = entry.gate && typeof entry.gate === 'object'
|
|
18038
|
+
? entry.gate
|
|
18039
|
+
: {};
|
|
18040
|
+
const gateActual = gate.actual && typeof gate.actual === 'object'
|
|
18041
|
+
? gate.actual
|
|
18042
|
+
: {};
|
|
18043
|
+
const explicit = toNumber(gateActual.moqui_matrix_regression_count);
|
|
18044
|
+
if (Number.isFinite(explicit)) {
|
|
18045
|
+
return Math.max(0, explicit);
|
|
18046
|
+
}
|
|
18047
|
+
const moquiBaseline = entry.moqui_baseline && typeof entry.moqui_baseline === 'object'
|
|
18048
|
+
? entry.moqui_baseline
|
|
18049
|
+
: {};
|
|
18050
|
+
const compare = moquiBaseline.compare && typeof moquiBaseline.compare === 'object'
|
|
18051
|
+
? moquiBaseline.compare
|
|
18052
|
+
: null;
|
|
18053
|
+
if (!compare) {
|
|
18054
|
+
return null;
|
|
18055
|
+
}
|
|
18056
|
+
return buildAutoHandoffMoquiCoverageRegressions(compare).length;
|
|
18057
|
+
};
|
|
18058
|
+
const deriveMoquiMatrixRegressionGateMax = entry => {
|
|
18059
|
+
if (!entry || typeof entry !== 'object') {
|
|
18060
|
+
return null;
|
|
18061
|
+
}
|
|
18062
|
+
const gate = entry.gate && typeof entry.gate === 'object'
|
|
18063
|
+
? entry.gate
|
|
18064
|
+
: {};
|
|
18065
|
+
const gateActual = gate.actual && typeof gate.actual === 'object'
|
|
18066
|
+
? gate.actual
|
|
18067
|
+
: {};
|
|
18068
|
+
const explicit = toNumber(gateActual.max_moqui_matrix_regressions);
|
|
18069
|
+
if (Number.isFinite(explicit)) {
|
|
18070
|
+
return Math.max(0, explicit);
|
|
18071
|
+
}
|
|
18072
|
+
const policy = entry.policy && typeof entry.policy === 'object'
|
|
18073
|
+
? entry.policy
|
|
18074
|
+
: {};
|
|
18075
|
+
const fromPolicy = toNumber(policy.max_moqui_matrix_regressions);
|
|
18076
|
+
return Number.isFinite(fromPolicy) ? Math.max(0, fromPolicy) : null;
|
|
18077
|
+
};
|
|
18078
|
+
const deriveCapabilityExpectedUnknownCount = entry => {
|
|
18079
|
+
if (!entry || typeof entry !== 'object') {
|
|
18080
|
+
return null;
|
|
18081
|
+
}
|
|
18082
|
+
const gate = entry.gate && typeof entry.gate === 'object'
|
|
18083
|
+
? entry.gate
|
|
18084
|
+
: {};
|
|
18085
|
+
const gateActual = gate.actual && typeof gate.actual === 'object'
|
|
18086
|
+
? gate.actual
|
|
18087
|
+
: {};
|
|
18088
|
+
const explicit = toNumber(gateActual.capability_expected_unknown_count);
|
|
18089
|
+
if (Number.isFinite(explicit)) {
|
|
18090
|
+
return Math.max(0, explicit);
|
|
18091
|
+
}
|
|
18092
|
+
const coverage = entry.capability_coverage && typeof entry.capability_coverage === 'object'
|
|
18093
|
+
? entry.capability_coverage
|
|
18094
|
+
: {};
|
|
18095
|
+
const normalization = coverage.normalization && typeof coverage.normalization === 'object'
|
|
18096
|
+
? coverage.normalization
|
|
18097
|
+
: {};
|
|
18098
|
+
const list = Array.isArray(normalization.expected_unknown) ? normalization.expected_unknown : null;
|
|
18099
|
+
return list ? list.length : null;
|
|
18100
|
+
};
|
|
18101
|
+
const deriveCapabilityProvidedUnknownCount = entry => {
|
|
18102
|
+
if (!entry || typeof entry !== 'object') {
|
|
18103
|
+
return null;
|
|
18104
|
+
}
|
|
18105
|
+
const gate = entry.gate && typeof entry.gate === 'object'
|
|
18106
|
+
? entry.gate
|
|
18107
|
+
: {};
|
|
18108
|
+
const gateActual = gate.actual && typeof gate.actual === 'object'
|
|
18109
|
+
? gate.actual
|
|
18110
|
+
: {};
|
|
18111
|
+
const explicit = toNumber(gateActual.capability_provided_unknown_count);
|
|
18112
|
+
if (Number.isFinite(explicit)) {
|
|
18113
|
+
return Math.max(0, explicit);
|
|
18114
|
+
}
|
|
18115
|
+
const coverage = entry.capability_coverage && typeof entry.capability_coverage === 'object'
|
|
18116
|
+
? entry.capability_coverage
|
|
18117
|
+
: {};
|
|
18118
|
+
const normalization = coverage.normalization && typeof coverage.normalization === 'object'
|
|
18119
|
+
? coverage.normalization
|
|
18120
|
+
: {};
|
|
18121
|
+
const list = Array.isArray(normalization.provided_unknown) ? normalization.provided_unknown : null;
|
|
18122
|
+
return list ? list.length : null;
|
|
18123
|
+
};
|
|
18124
|
+
const latestMoquiMatrixRegressionCount = deriveMoquiMatrixRegressionCount(latest);
|
|
18125
|
+
const latestMoquiMatrixRegressionGateMax = deriveMoquiMatrixRegressionGateMax(latest);
|
|
18126
|
+
const latestCapabilityExpectedUnknownCount = deriveCapabilityExpectedUnknownCount(latest);
|
|
18127
|
+
const latestCapabilityProvidedUnknownCount = deriveCapabilityProvidedUnknownCount(latest);
|
|
17301
18128
|
|
|
17302
18129
|
let failedRuns = 0;
|
|
17303
18130
|
let gateKnownRuns = 0;
|
|
@@ -17306,7 +18133,14 @@ async function loadGovernanceHandoffQualitySignals(projectPath) {
|
|
|
17306
18133
|
let capabilityPassedRuns = 0;
|
|
17307
18134
|
let sceneBatchKnownRuns = 0;
|
|
17308
18135
|
let sceneBatchPassedRuns = 0;
|
|
18136
|
+
let capabilityExpectedUnknownKnownRuns = 0;
|
|
18137
|
+
let capabilityExpectedUnknownPositiveRuns = 0;
|
|
18138
|
+
let capabilityProvidedUnknownKnownRuns = 0;
|
|
18139
|
+
let capabilityProvidedUnknownPositiveRuns = 0;
|
|
18140
|
+
let moquiMatrixKnownRuns = 0;
|
|
18141
|
+
let moquiMatrixPositiveRuns = 0;
|
|
17309
18142
|
const ontologyScores = [];
|
|
18143
|
+
const moquiMatrixRegressionCounts = [];
|
|
17310
18144
|
for (const entry of sessions) {
|
|
17311
18145
|
const status = normalizeHandoffText(entry && entry.status);
|
|
17312
18146
|
if (status && !['completed', 'dry-run', 'dry_run'].includes(status)) {
|
|
@@ -17359,6 +18193,28 @@ async function loadGovernanceHandoffQualitySignals(projectPath) {
|
|
|
17359
18193
|
if (Number.isFinite(ontologyScore)) {
|
|
17360
18194
|
ontologyScores.push(ontologyScore);
|
|
17361
18195
|
}
|
|
18196
|
+
const capabilityExpectedUnknownCount = deriveCapabilityExpectedUnknownCount(entry);
|
|
18197
|
+
if (Number.isFinite(capabilityExpectedUnknownCount)) {
|
|
18198
|
+
capabilityExpectedUnknownKnownRuns += 1;
|
|
18199
|
+
if (capabilityExpectedUnknownCount > 0) {
|
|
18200
|
+
capabilityExpectedUnknownPositiveRuns += 1;
|
|
18201
|
+
}
|
|
18202
|
+
}
|
|
18203
|
+
const capabilityProvidedUnknownCount = deriveCapabilityProvidedUnknownCount(entry);
|
|
18204
|
+
if (Number.isFinite(capabilityProvidedUnknownCount)) {
|
|
18205
|
+
capabilityProvidedUnknownKnownRuns += 1;
|
|
18206
|
+
if (capabilityProvidedUnknownCount > 0) {
|
|
18207
|
+
capabilityProvidedUnknownPositiveRuns += 1;
|
|
18208
|
+
}
|
|
18209
|
+
}
|
|
18210
|
+
const moquiMatrixRegressionCount = deriveMoquiMatrixRegressionCount(entry);
|
|
18211
|
+
if (Number.isFinite(moquiMatrixRegressionCount)) {
|
|
18212
|
+
moquiMatrixKnownRuns += 1;
|
|
18213
|
+
moquiMatrixRegressionCounts.push(Math.max(0, moquiMatrixRegressionCount));
|
|
18214
|
+
if (moquiMatrixRegressionCount > 0) {
|
|
18215
|
+
moquiMatrixPositiveRuns += 1;
|
|
18216
|
+
}
|
|
18217
|
+
}
|
|
17362
18218
|
}
|
|
17363
18219
|
|
|
17364
18220
|
return {
|
|
@@ -17379,6 +18235,18 @@ async function loadGovernanceHandoffQualitySignals(projectPath) {
|
|
|
17379
18235
|
),
|
|
17380
18236
|
latest_capability_coverage_percent: toNumber(latestCapabilitySummary.coverage_percent),
|
|
17381
18237
|
latest_capability_coverage_passed: parseAutoHandoffGateBoolean(latestCapabilitySummary.passed, null),
|
|
18238
|
+
latest_capability_expected_unknown_count: Number.isFinite(latestCapabilityExpectedUnknownCount)
|
|
18239
|
+
? latestCapabilityExpectedUnknownCount
|
|
18240
|
+
: null,
|
|
18241
|
+
latest_capability_provided_unknown_count: Number.isFinite(latestCapabilityProvidedUnknownCount)
|
|
18242
|
+
? latestCapabilityProvidedUnknownCount
|
|
18243
|
+
: null,
|
|
18244
|
+
latest_moqui_matrix_regression_count: Number.isFinite(latestMoquiMatrixRegressionCount)
|
|
18245
|
+
? latestMoquiMatrixRegressionCount
|
|
18246
|
+
: null,
|
|
18247
|
+
latest_moqui_matrix_regression_gate_max: Number.isFinite(latestMoquiMatrixRegressionGateMax)
|
|
18248
|
+
? latestMoquiMatrixRegressionGateMax
|
|
18249
|
+
: null,
|
|
17382
18250
|
latest_scene_package_batch_passed: parseAutoHandoffGateBoolean(latestSceneSummary.batch_gate_passed, null),
|
|
17383
18251
|
latest_release_gate_preflight_blocked: parseAutoHandoffGateBoolean(latestPreflight.blocked, null),
|
|
17384
18252
|
latest_failure_highlights: latestFailureHighlights,
|
|
@@ -17389,6 +18257,27 @@ async function loadGovernanceHandoffQualitySignals(projectPath) {
|
|
|
17389
18257
|
avg_ontology_quality_score: ontologyScores.length > 0
|
|
17390
18258
|
? Number((ontologyScores.reduce((sum, item) => sum + item, 0) / ontologyScores.length).toFixed(2))
|
|
17391
18259
|
: null,
|
|
18260
|
+
capability_expected_unknown_positive_rate_percent: toPercent(
|
|
18261
|
+
capabilityExpectedUnknownPositiveRuns,
|
|
18262
|
+
capabilityExpectedUnknownKnownRuns
|
|
18263
|
+
),
|
|
18264
|
+
capability_provided_unknown_positive_rate_percent: toPercent(
|
|
18265
|
+
capabilityProvidedUnknownPositiveRuns,
|
|
18266
|
+
capabilityProvidedUnknownKnownRuns
|
|
18267
|
+
),
|
|
18268
|
+
avg_moqui_matrix_regression_count: moquiMatrixRegressionCounts.length > 0
|
|
18269
|
+
? Number((
|
|
18270
|
+
moquiMatrixRegressionCounts.reduce((sum, item) => sum + item, 0) /
|
|
18271
|
+
moquiMatrixRegressionCounts.length
|
|
18272
|
+
).toFixed(2))
|
|
18273
|
+
: null,
|
|
18274
|
+
max_moqui_matrix_regression_count: moquiMatrixRegressionCounts.length > 0
|
|
18275
|
+
? Number(Math.max(...moquiMatrixRegressionCounts).toFixed(2))
|
|
18276
|
+
: null,
|
|
18277
|
+
moqui_matrix_regression_positive_rate_percent: toPercent(
|
|
18278
|
+
moquiMatrixPositiveRuns,
|
|
18279
|
+
moquiMatrixKnownRuns
|
|
18280
|
+
),
|
|
17392
18281
|
parse_error: null
|
|
17393
18282
|
};
|
|
17394
18283
|
}
|
|
@@ -17417,10 +18306,46 @@ function deriveGovernanceRiskLevel(summary) {
|
|
|
17417
18306
|
const handoffFailureRate = Number(handoffQuality.failure_rate_percent);
|
|
17418
18307
|
const handoffGatePassRate = Number(handoffQuality.gate_pass_rate_percent);
|
|
17419
18308
|
const handoffCapabilityPassRate = Number(handoffQuality.capability_coverage_pass_rate_percent);
|
|
18309
|
+
const handoffLatestCapabilityExpectedUnknownCount = Number(
|
|
18310
|
+
handoffQuality.latest_capability_expected_unknown_count
|
|
18311
|
+
);
|
|
18312
|
+
const handoffLatestCapabilityProvidedUnknownCount = Number(
|
|
18313
|
+
handoffQuality.latest_capability_provided_unknown_count
|
|
18314
|
+
);
|
|
18315
|
+
const handoffCapabilityExpectedUnknownPositiveRate = Number(
|
|
18316
|
+
handoffQuality.capability_expected_unknown_positive_rate_percent
|
|
18317
|
+
);
|
|
18318
|
+
const handoffCapabilityProvidedUnknownPositiveRate = Number(
|
|
18319
|
+
handoffQuality.capability_provided_unknown_positive_rate_percent
|
|
18320
|
+
);
|
|
18321
|
+
const handoffLatestMoquiMatrixRegressionCount = Number(handoffQuality.latest_moqui_matrix_regression_count);
|
|
18322
|
+
const handoffLatestMoquiMatrixRegressionGateMax = Number(handoffQuality.latest_moqui_matrix_regression_gate_max);
|
|
18323
|
+
const handoffMoquiMatrixRegressionPositiveRate = Number(handoffQuality.moqui_matrix_regression_positive_rate_percent);
|
|
17420
18324
|
const handoffPreflightBlocked = parseAutoHandoffGateBoolean(
|
|
17421
18325
|
handoffQuality.latest_release_gate_preflight_blocked,
|
|
17422
18326
|
null
|
|
17423
18327
|
);
|
|
18328
|
+
const handoffMatrixRegressionPositive = (
|
|
18329
|
+
Number.isFinite(handoffLatestMoquiMatrixRegressionCount) &&
|
|
18330
|
+
handoffLatestMoquiMatrixRegressionCount > 0
|
|
18331
|
+
);
|
|
18332
|
+
const handoffMatrixRegressionOverGate = (
|
|
18333
|
+
handoffMatrixRegressionPositive &&
|
|
18334
|
+
Number.isFinite(handoffLatestMoquiMatrixRegressionGateMax) &&
|
|
18335
|
+
handoffLatestMoquiMatrixRegressionCount > handoffLatestMoquiMatrixRegressionGateMax
|
|
18336
|
+
);
|
|
18337
|
+
const handoffMatrixRegressionPressureHigh = (
|
|
18338
|
+
Number.isFinite(handoffMoquiMatrixRegressionPositiveRate) &&
|
|
18339
|
+
handoffMoquiMatrixRegressionPositiveRate >= 50
|
|
18340
|
+
);
|
|
18341
|
+
const handoffCapabilityLexiconUnknownPositive = (
|
|
18342
|
+
(Number.isFinite(handoffLatestCapabilityExpectedUnknownCount) && handoffLatestCapabilityExpectedUnknownCount > 0) ||
|
|
18343
|
+
(Number.isFinite(handoffLatestCapabilityProvidedUnknownCount) && handoffLatestCapabilityProvidedUnknownCount > 0)
|
|
18344
|
+
);
|
|
18345
|
+
const handoffCapabilityLexiconUnknownPressureHigh = (
|
|
18346
|
+
(Number.isFinite(handoffCapabilityExpectedUnknownPositiveRate) && handoffCapabilityExpectedUnknownPositiveRate >= 50) ||
|
|
18347
|
+
(Number.isFinite(handoffCapabilityProvidedUnknownPositiveRate) && handoffCapabilityProvidedUnknownPositiveRate >= 50)
|
|
18348
|
+
);
|
|
17424
18349
|
|
|
17425
18350
|
let riskLevel = 'low';
|
|
17426
18351
|
if (failureRate >= 40 || pendingGoals >= 5) {
|
|
@@ -17461,7 +18386,11 @@ function deriveGovernanceRiskLevel(summary) {
|
|
|
17461
18386
|
handoffFailed ||
|
|
17462
18387
|
handoffHighFailureRate ||
|
|
17463
18388
|
handoffPreflightBlocked === true ||
|
|
17464
|
-
|
|
18389
|
+
handoffMatrixRegressionOverGate ||
|
|
18390
|
+
handoffCapabilityLexiconUnknownPositive ||
|
|
18391
|
+
(handoffLatestGatePassed === false && handoffSevereQualityDrop) ||
|
|
18392
|
+
(handoffMatrixRegressionPositive && handoffMatrixRegressionPressureHigh) ||
|
|
18393
|
+
handoffCapabilityLexiconUnknownPressureHigh
|
|
17465
18394
|
) {
|
|
17466
18395
|
riskLevel = 'high';
|
|
17467
18396
|
} else if (
|
|
@@ -17470,7 +18399,11 @@ function deriveGovernanceRiskLevel(summary) {
|
|
|
17470
18399
|
(Number.isFinite(handoffGatePassRate) && handoffGatePassRate < 85) ||
|
|
17471
18400
|
(Number.isFinite(handoffCapabilityPassRate) && handoffCapabilityPassRate < 85) ||
|
|
17472
18401
|
(Number.isFinite(handoffLatestOntologyScore) && handoffLatestOntologyScore < 85) ||
|
|
17473
|
-
(Number.isFinite(handoffFailureRate) && handoffFailureRate > 0)
|
|
18402
|
+
(Number.isFinite(handoffFailureRate) && handoffFailureRate > 0) ||
|
|
18403
|
+
handoffMatrixRegressionPositive ||
|
|
18404
|
+
(Number.isFinite(handoffMoquiMatrixRegressionPositiveRate) && handoffMoquiMatrixRegressionPositiveRate > 0) ||
|
|
18405
|
+
(Number.isFinite(handoffCapabilityExpectedUnknownPositiveRate) && handoffCapabilityExpectedUnknownPositiveRate > 0) ||
|
|
18406
|
+
(Number.isFinite(handoffCapabilityProvidedUnknownPositiveRate) && handoffCapabilityProvidedUnknownPositiveRate > 0)
|
|
17474
18407
|
)
|
|
17475
18408
|
) {
|
|
17476
18409
|
riskLevel = 'medium';
|
|
@@ -17505,6 +18438,22 @@ function buildGovernanceConcerns(summary) {
|
|
|
17505
18438
|
const handoffLatestOntologyScore = Number(handoffQuality.latest_ontology_quality_score);
|
|
17506
18439
|
const handoffFailureRate = Number(handoffQuality.failure_rate_percent);
|
|
17507
18440
|
const handoffCapabilityPassRate = Number(handoffQuality.capability_coverage_pass_rate_percent);
|
|
18441
|
+
const handoffLatestCapabilityExpectedUnknownCount = Number(
|
|
18442
|
+
handoffQuality.latest_capability_expected_unknown_count
|
|
18443
|
+
);
|
|
18444
|
+
const handoffLatestCapabilityProvidedUnknownCount = Number(
|
|
18445
|
+
handoffQuality.latest_capability_provided_unknown_count
|
|
18446
|
+
);
|
|
18447
|
+
const handoffCapabilityExpectedUnknownPositiveRate = Number(
|
|
18448
|
+
handoffQuality.capability_expected_unknown_positive_rate_percent
|
|
18449
|
+
);
|
|
18450
|
+
const handoffCapabilityProvidedUnknownPositiveRate = Number(
|
|
18451
|
+
handoffQuality.capability_provided_unknown_positive_rate_percent
|
|
18452
|
+
);
|
|
18453
|
+
const handoffLatestMoquiMatrixRegressionCount = Number(handoffQuality.latest_moqui_matrix_regression_count);
|
|
18454
|
+
const handoffLatestMoquiMatrixRegressionGateMax = Number(handoffQuality.latest_moqui_matrix_regression_gate_max);
|
|
18455
|
+
const handoffMaxMoquiMatrixRegressionCount = Number(handoffQuality.max_moqui_matrix_regression_count);
|
|
18456
|
+
const handoffMoquiMatrixRegressionPositiveRate = Number(handoffQuality.moqui_matrix_regression_positive_rate_percent);
|
|
17508
18457
|
const handoffPreflightBlocked = parseAutoHandoffGateBoolean(
|
|
17509
18458
|
handoffQuality.latest_release_gate_preflight_blocked,
|
|
17510
18459
|
null
|
|
@@ -17567,6 +18516,61 @@ function buildGovernanceConcerns(summary) {
|
|
|
17567
18516
|
if (Number.isFinite(handoffCapabilityPassRate) && handoffCapabilityPassRate < 85) {
|
|
17568
18517
|
concerns.push(`Handoff capability coverage pass rate is low at ${handoffCapabilityPassRate}%.`);
|
|
17569
18518
|
}
|
|
18519
|
+
if (
|
|
18520
|
+
Number.isFinite(handoffLatestCapabilityExpectedUnknownCount) &&
|
|
18521
|
+
handoffLatestCapabilityExpectedUnknownCount > 0
|
|
18522
|
+
) {
|
|
18523
|
+
concerns.push(
|
|
18524
|
+
`Latest handoff manifest capability unknown count is ${handoffLatestCapabilityExpectedUnknownCount}.`
|
|
18525
|
+
);
|
|
18526
|
+
}
|
|
18527
|
+
if (
|
|
18528
|
+
Number.isFinite(handoffLatestCapabilityProvidedUnknownCount) &&
|
|
18529
|
+
handoffLatestCapabilityProvidedUnknownCount > 0
|
|
18530
|
+
) {
|
|
18531
|
+
concerns.push(
|
|
18532
|
+
`Latest handoff template capability unknown count is ${handoffLatestCapabilityProvidedUnknownCount}.`
|
|
18533
|
+
);
|
|
18534
|
+
}
|
|
18535
|
+
if (
|
|
18536
|
+
Number.isFinite(handoffCapabilityExpectedUnknownPositiveRate) &&
|
|
18537
|
+
handoffCapabilityExpectedUnknownPositiveRate > 0
|
|
18538
|
+
) {
|
|
18539
|
+
concerns.push(
|
|
18540
|
+
`Handoff manifest capability unknown positive rate is ${handoffCapabilityExpectedUnknownPositiveRate}%.`
|
|
18541
|
+
);
|
|
18542
|
+
}
|
|
18543
|
+
if (
|
|
18544
|
+
Number.isFinite(handoffCapabilityProvidedUnknownPositiveRate) &&
|
|
18545
|
+
handoffCapabilityProvidedUnknownPositiveRate > 0
|
|
18546
|
+
) {
|
|
18547
|
+
concerns.push(
|
|
18548
|
+
`Handoff template capability unknown positive rate is ${handoffCapabilityProvidedUnknownPositiveRate}%.`
|
|
18549
|
+
);
|
|
18550
|
+
}
|
|
18551
|
+
if (Number.isFinite(handoffLatestMoquiMatrixRegressionCount) && handoffLatestMoquiMatrixRegressionCount > 0) {
|
|
18552
|
+
concerns.push(
|
|
18553
|
+
`Latest handoff Moqui matrix regression count is ${handoffLatestMoquiMatrixRegressionCount}.`
|
|
18554
|
+
);
|
|
18555
|
+
}
|
|
18556
|
+
if (
|
|
18557
|
+
Number.isFinite(handoffLatestMoquiMatrixRegressionCount) &&
|
|
18558
|
+
Number.isFinite(handoffLatestMoquiMatrixRegressionGateMax) &&
|
|
18559
|
+
handoffLatestMoquiMatrixRegressionCount > handoffLatestMoquiMatrixRegressionGateMax
|
|
18560
|
+
) {
|
|
18561
|
+
concerns.push(
|
|
18562
|
+
`Latest handoff Moqui matrix regressions exceed gate (${handoffLatestMoquiMatrixRegressionCount} > ` +
|
|
18563
|
+
`${handoffLatestMoquiMatrixRegressionGateMax}).`
|
|
18564
|
+
);
|
|
18565
|
+
}
|
|
18566
|
+
if (Number.isFinite(handoffMoquiMatrixRegressionPositiveRate) && handoffMoquiMatrixRegressionPositiveRate > 0) {
|
|
18567
|
+
concerns.push(
|
|
18568
|
+
`Handoff Moqui matrix regression positive rate is ${handoffMoquiMatrixRegressionPositiveRate}%.`
|
|
18569
|
+
);
|
|
18570
|
+
}
|
|
18571
|
+
if (Number.isFinite(handoffMaxMoquiMatrixRegressionCount) && handoffMaxMoquiMatrixRegressionCount > 0) {
|
|
18572
|
+
concerns.push(`Handoff Moqui matrix regression max is ${handoffMaxMoquiMatrixRegressionCount}.`);
|
|
18573
|
+
}
|
|
17570
18574
|
}
|
|
17571
18575
|
|
|
17572
18576
|
return concerns;
|
|
@@ -17594,6 +18598,21 @@ function buildGovernanceRecommendations(summary) {
|
|
|
17594
18598
|
const handoffLatestGatePassed = parseAutoHandoffGateBoolean(handoffQuality.latest_gate_passed, null);
|
|
17595
18599
|
const handoffFailureRate = Number(handoffQuality.failure_rate_percent);
|
|
17596
18600
|
const handoffCapabilityPassRate = Number(handoffQuality.capability_coverage_pass_rate_percent);
|
|
18601
|
+
const handoffLatestCapabilityExpectedUnknownCount = Number(
|
|
18602
|
+
handoffQuality.latest_capability_expected_unknown_count
|
|
18603
|
+
);
|
|
18604
|
+
const handoffLatestCapabilityProvidedUnknownCount = Number(
|
|
18605
|
+
handoffQuality.latest_capability_provided_unknown_count
|
|
18606
|
+
);
|
|
18607
|
+
const handoffCapabilityExpectedUnknownPositiveRate = Number(
|
|
18608
|
+
handoffQuality.capability_expected_unknown_positive_rate_percent
|
|
18609
|
+
);
|
|
18610
|
+
const handoffCapabilityProvidedUnknownPositiveRate = Number(
|
|
18611
|
+
handoffQuality.capability_provided_unknown_positive_rate_percent
|
|
18612
|
+
);
|
|
18613
|
+
const handoffLatestMoquiMatrixRegressionCount = Number(handoffQuality.latest_moqui_matrix_regression_count);
|
|
18614
|
+
const handoffLatestMoquiMatrixRegressionGateMax = Number(handoffQuality.latest_moqui_matrix_regression_gate_max);
|
|
18615
|
+
const handoffMoquiMatrixRegressionPositiveRate = Number(handoffQuality.moqui_matrix_regression_positive_rate_percent);
|
|
17597
18616
|
const handoffPreflightBlocked = parseAutoHandoffGateBoolean(
|
|
17598
18617
|
handoffQuality.latest_release_gate_preflight_blocked,
|
|
17599
18618
|
null
|
|
@@ -17635,6 +18654,15 @@ function buildGovernanceRecommendations(summary) {
|
|
|
17635
18654
|
'`sce auto handoff run --manifest docs/handoffs/handoff-manifest.json --dry-run --json`.'
|
|
17636
18655
|
);
|
|
17637
18656
|
} else if (handoffTotalRuns > 0) {
|
|
18657
|
+
const handoffMoquiMatrixRegressionPositive = (
|
|
18658
|
+
Number.isFinite(handoffLatestMoquiMatrixRegressionCount) &&
|
|
18659
|
+
handoffLatestMoquiMatrixRegressionCount > 0
|
|
18660
|
+
);
|
|
18661
|
+
const handoffMoquiMatrixRegressionOverGate = (
|
|
18662
|
+
handoffMoquiMatrixRegressionPositive &&
|
|
18663
|
+
Number.isFinite(handoffLatestMoquiMatrixRegressionGateMax) &&
|
|
18664
|
+
handoffLatestMoquiMatrixRegressionCount > handoffLatestMoquiMatrixRegressionGateMax
|
|
18665
|
+
);
|
|
17638
18666
|
if (
|
|
17639
18667
|
(handoffLatestStatus && !['completed', 'dry-run', 'dry_run'].includes(handoffLatestStatus)) ||
|
|
17640
18668
|
handoffLatestGatePassed === false ||
|
|
@@ -17655,6 +18683,38 @@ function buildGovernanceRecommendations(summary) {
|
|
|
17655
18683
|
'`sce auto handoff run --manifest docs/handoffs/handoff-manifest.json --dry-run --json`.'
|
|
17656
18684
|
);
|
|
17657
18685
|
}
|
|
18686
|
+
if (
|
|
18687
|
+
(Number.isFinite(handoffLatestCapabilityExpectedUnknownCount) && handoffLatestCapabilityExpectedUnknownCount > 0) ||
|
|
18688
|
+
(Number.isFinite(handoffLatestCapabilityProvidedUnknownCount) && handoffLatestCapabilityProvidedUnknownCount > 0) ||
|
|
18689
|
+
(Number.isFinite(handoffCapabilityExpectedUnknownPositiveRate) && handoffCapabilityExpectedUnknownPositiveRate > 0) ||
|
|
18690
|
+
(Number.isFinite(handoffCapabilityProvidedUnknownPositiveRate) && handoffCapabilityProvidedUnknownPositiveRate > 0)
|
|
18691
|
+
) {
|
|
18692
|
+
recommendations.push(
|
|
18693
|
+
'Normalize capability lexicon gaps with ' +
|
|
18694
|
+
'`node scripts/moqui-lexicon-audit.js --manifest docs/handoffs/handoff-manifest.json ' +
|
|
18695
|
+
'--template-dir .kiro/templates/scene-packages --fail-on-gap --json`.'
|
|
18696
|
+
);
|
|
18697
|
+
recommendations.push(
|
|
18698
|
+
'Re-run strict handoff lexicon gates with ' +
|
|
18699
|
+
'`sce auto handoff run --manifest docs/handoffs/handoff-manifest.json --dry-run --json`.'
|
|
18700
|
+
);
|
|
18701
|
+
}
|
|
18702
|
+
if (
|
|
18703
|
+
handoffMoquiMatrixRegressionPositive ||
|
|
18704
|
+
handoffMoquiMatrixRegressionOverGate ||
|
|
18705
|
+
(Number.isFinite(handoffMoquiMatrixRegressionPositiveRate) && handoffMoquiMatrixRegressionPositiveRate > 0)
|
|
18706
|
+
) {
|
|
18707
|
+
recommendations.push(
|
|
18708
|
+
'Recover Moqui matrix regressions via ' +
|
|
18709
|
+
'`sce auto handoff run --manifest docs/handoffs/handoff-manifest.json ' +
|
|
18710
|
+
'--dry-run --max-moqui-matrix-regressions 0 --json`.'
|
|
18711
|
+
);
|
|
18712
|
+
recommendations.push(
|
|
18713
|
+
'Inspect Moqui baseline matrix drift with ' +
|
|
18714
|
+
'`sce scene moqui-baseline --include-all ' +
|
|
18715
|
+
'--compare-with .kiro/reports/release-evidence/moqui-template-baseline.json --json`.'
|
|
18716
|
+
);
|
|
18717
|
+
}
|
|
17658
18718
|
}
|
|
17659
18719
|
|
|
17660
18720
|
return Array.from(new Set(recommendations));
|
|
@@ -19002,12 +20062,64 @@ function evaluateGovernanceReleaseGateBlockState(assessment) {
|
|
|
19002
20062
|
if (handoffSnapshot.latest_capability_coverage_passed === false) {
|
|
19003
20063
|
reasons.push('handoff-capability-coverage-failed');
|
|
19004
20064
|
}
|
|
20065
|
+
if (
|
|
20066
|
+
Number.isFinite(handoffSnapshot.latest_capability_expected_unknown_count) &&
|
|
20067
|
+
handoffSnapshot.latest_capability_expected_unknown_count > 0
|
|
20068
|
+
) {
|
|
20069
|
+
reasons.push(
|
|
20070
|
+
`handoff-capability-expected-unknown-positive:${handoffSnapshot.latest_capability_expected_unknown_count}`
|
|
20071
|
+
);
|
|
20072
|
+
}
|
|
20073
|
+
if (
|
|
20074
|
+
Number.isFinite(handoffSnapshot.latest_capability_provided_unknown_count) &&
|
|
20075
|
+
handoffSnapshot.latest_capability_provided_unknown_count > 0
|
|
20076
|
+
) {
|
|
20077
|
+
reasons.push(
|
|
20078
|
+
`handoff-capability-provided-unknown-positive:${handoffSnapshot.latest_capability_provided_unknown_count}`
|
|
20079
|
+
);
|
|
20080
|
+
}
|
|
20081
|
+
if (
|
|
20082
|
+
Number.isFinite(handoffSnapshot.capability_expected_unknown_positive_rate_percent) &&
|
|
20083
|
+
handoffSnapshot.capability_expected_unknown_positive_rate_percent > 0
|
|
20084
|
+
) {
|
|
20085
|
+
reasons.push(
|
|
20086
|
+
`handoff-capability-expected-unknown-positive-rate:` +
|
|
20087
|
+
`${handoffSnapshot.capability_expected_unknown_positive_rate_percent}`
|
|
20088
|
+
);
|
|
20089
|
+
}
|
|
20090
|
+
if (
|
|
20091
|
+
Number.isFinite(handoffSnapshot.capability_provided_unknown_positive_rate_percent) &&
|
|
20092
|
+
handoffSnapshot.capability_provided_unknown_positive_rate_percent > 0
|
|
20093
|
+
) {
|
|
20094
|
+
reasons.push(
|
|
20095
|
+
`handoff-capability-provided-unknown-positive-rate:` +
|
|
20096
|
+
`${handoffSnapshot.capability_provided_unknown_positive_rate_percent}`
|
|
20097
|
+
);
|
|
20098
|
+
}
|
|
19005
20099
|
if (handoffSnapshot.latest_release_gate_preflight_blocked === true) {
|
|
19006
20100
|
reasons.push('handoff-release-preflight-blocked');
|
|
19007
20101
|
}
|
|
19008
20102
|
if (Number.isFinite(handoffSnapshot.failure_rate_percent) && handoffSnapshot.failure_rate_percent > 0) {
|
|
19009
20103
|
reasons.push(`handoff-failure-rate-positive:${handoffSnapshot.failure_rate_percent}`);
|
|
19010
20104
|
}
|
|
20105
|
+
const handoffLatestMoquiMatrixRegressionCount = Number(handoffSnapshot.latest_moqui_matrix_regression_count);
|
|
20106
|
+
const handoffLatestMoquiMatrixRegressionGateMax = Number(handoffSnapshot.latest_moqui_matrix_regression_gate_max);
|
|
20107
|
+
if (
|
|
20108
|
+
Number.isFinite(handoffLatestMoquiMatrixRegressionCount) &&
|
|
20109
|
+
handoffLatestMoquiMatrixRegressionCount > 0
|
|
20110
|
+
) {
|
|
20111
|
+
reasons.push(`handoff-moqui-matrix-regressions-positive:${handoffLatestMoquiMatrixRegressionCount}`);
|
|
20112
|
+
}
|
|
20113
|
+
if (
|
|
20114
|
+
Number.isFinite(handoffLatestMoquiMatrixRegressionCount) &&
|
|
20115
|
+
Number.isFinite(handoffLatestMoquiMatrixRegressionGateMax) &&
|
|
20116
|
+
handoffLatestMoquiMatrixRegressionCount > handoffLatestMoquiMatrixRegressionGateMax
|
|
20117
|
+
) {
|
|
20118
|
+
reasons.push(
|
|
20119
|
+
`handoff-moqui-matrix-regressions-over-gate:` +
|
|
20120
|
+
`${handoffLatestMoquiMatrixRegressionCount}/${handoffLatestMoquiMatrixRegressionGateMax}`
|
|
20121
|
+
);
|
|
20122
|
+
}
|
|
19011
20123
|
}
|
|
19012
20124
|
|
|
19013
20125
|
const blockedByReleaseGate = Boolean(
|
|
@@ -19024,7 +20136,13 @@ function evaluateGovernanceReleaseGateBlockState(assessment) {
|
|
|
19024
20136
|
|| `${item}` === 'handoff-latest-gate-failed'
|
|
19025
20137
|
|| `${item}`.startsWith('handoff-ontology-score-low:')
|
|
19026
20138
|
|| `${item}` === 'handoff-capability-coverage-failed'
|
|
20139
|
+
|| `${item}`.startsWith('handoff-capability-expected-unknown-positive:')
|
|
20140
|
+
|| `${item}`.startsWith('handoff-capability-provided-unknown-positive:')
|
|
20141
|
+
|| `${item}`.startsWith('handoff-capability-expected-unknown-positive-rate:')
|
|
20142
|
+
|| `${item}`.startsWith('handoff-capability-provided-unknown-positive-rate:')
|
|
19027
20143
|
|| `${item}` === 'handoff-release-preflight-blocked'
|
|
20144
|
+
|| `${item}`.startsWith('handoff-moqui-matrix-regressions-positive:')
|
|
20145
|
+
|| `${item}`.startsWith('handoff-moqui-matrix-regressions-over-gate:')
|
|
19028
20146
|
));
|
|
19029
20147
|
const blocked = reasons.length > 0 && (blockedByReleaseGate || blockedByHandoffQuality);
|
|
19030
20148
|
return {
|
|
@@ -19066,6 +20184,29 @@ function buildGovernanceCloseLoopRecommendations(finalAssessment, stopReason, st
|
|
|
19066
20184
|
'`sce auto handoff run --manifest docs/handoffs/handoff-manifest.json --continue-from latest --continue-strategy failed-only --json`.'
|
|
19067
20185
|
);
|
|
19068
20186
|
}
|
|
20187
|
+
if (reasons.some(item => `${item}`.startsWith('handoff-moqui-matrix-regressions-'))) {
|
|
20188
|
+
base.push(
|
|
20189
|
+
'Recover Moqui matrix regressions with ' +
|
|
20190
|
+
'`sce auto handoff run --manifest docs/handoffs/handoff-manifest.json ' +
|
|
20191
|
+
'--dry-run --max-moqui-matrix-regressions 0 --json`.'
|
|
20192
|
+
);
|
|
20193
|
+
base.push(
|
|
20194
|
+
'Inspect Moqui matrix drift with ' +
|
|
20195
|
+
'`sce scene moqui-baseline --include-all ' +
|
|
20196
|
+
'--compare-with .kiro/reports/release-evidence/moqui-template-baseline.json --json`.'
|
|
20197
|
+
);
|
|
20198
|
+
}
|
|
20199
|
+
if (reasons.some(item => `${item}`.startsWith('handoff-capability-') && `${item}`.includes('unknown'))) {
|
|
20200
|
+
base.push(
|
|
20201
|
+
'Normalize capability lexicon gaps with ' +
|
|
20202
|
+
'`node scripts/moqui-lexicon-audit.js --manifest docs/handoffs/handoff-manifest.json ' +
|
|
20203
|
+
'--template-dir .kiro/templates/scene-packages --fail-on-gap --json`.'
|
|
20204
|
+
);
|
|
20205
|
+
base.push(
|
|
20206
|
+
'Re-run strict handoff gates after lexicon normalization with ' +
|
|
20207
|
+
'`sce auto handoff run --manifest docs/handoffs/handoff-manifest.json --dry-run --json`.'
|
|
20208
|
+
);
|
|
20209
|
+
}
|
|
19069
20210
|
return Array.from(new Set(base));
|
|
19070
20211
|
}
|
|
19071
20212
|
|