scene-capability-engine 3.6.32 → 3.6.36
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 +86 -1
- package/README.md +119 -122
- package/README.zh.md +123 -121
- package/bin/scene-capability-engine.js +11 -0
- package/docs/README.md +21 -32
- package/docs/auto-refactor-index.md +384 -0
- package/docs/command-reference.md +94 -2
- package/docs/magicball-adaptation-task-checklist-v1.md +385 -0
- package/docs/magicball-app-bundle-sqlite-and-command-draft.md +539 -0
- package/docs/magicball-capability-iteration-api.md +2 -0
- package/docs/magicball-capability-iteration-ui.md +2 -0
- package/docs/magicball-capability-library.md +2 -0
- package/docs/magicball-cli-invocation-examples.md +336 -0
- package/docs/magicball-frontend-state-and-command-mapping.md +244 -0
- package/docs/magicball-integration-doc-index.md +137 -0
- package/docs/magicball-integration-issue-tracker.md +218 -0
- package/docs/magicball-mode-home-and-ontology-empty-state-playbook.md +249 -0
- package/docs/magicball-sce-adaptation-guide.md +203 -0
- package/docs/magicball-three-mode-alignment-plan.md +551 -0
- package/docs/magicball-ui-surface-checklist.md +126 -0
- package/docs/magicball-write-auth-adaptation-guide.md +328 -0
- package/docs/refactor-completion-roadmap.md +116 -0
- package/docs/zh/README.md +27 -30
- package/docs/zh/refactor-completion-roadmap.md +116 -0
- package/lib/app/registry-config.js +73 -0
- package/lib/app/registry-sync-service.js +228 -0
- package/lib/auto/archive-schema-service.js +276 -0
- package/lib/auto/archive-summary.js +60 -0
- package/lib/auto/batch-goal-input-service.js +543 -0
- package/lib/auto/batch-output.js +201 -0
- package/lib/auto/batch-summary-storage-service.js +110 -0
- package/lib/auto/close-loop-batch-service.js +116 -0
- package/lib/auto/close-loop-controller-service.js +287 -0
- package/lib/auto/close-loop-program-service.js +283 -0
- package/lib/auto/close-loop-recovery-service.js +191 -0
- package/lib/auto/close-loop-session-storage-service.js +50 -0
- package/lib/auto/controller-lock-service.js +55 -0
- package/lib/auto/controller-output.js +32 -0
- package/lib/auto/controller-queue-service.js +127 -0
- package/lib/auto/controller-session-storage-service.js +105 -0
- package/lib/auto/governance-advisory-service.js +208 -0
- package/lib/auto/governance-close-loop-service.js +411 -0
- package/lib/auto/governance-maintenance-presenter.js +162 -0
- package/lib/auto/governance-maintenance-service.js +112 -0
- package/lib/auto/governance-session-presenter.js +70 -0
- package/lib/auto/governance-session-storage-service.js +198 -0
- package/lib/auto/governance-signals.js +139 -0
- package/lib/auto/governance-stats-presenter.js +337 -0
- package/lib/auto/governance-stats-service.js +115 -0
- package/lib/auto/governance-summary.js +703 -0
- package/lib/auto/handoff-capability-matrix-service.js +281 -0
- package/lib/auto/handoff-evidence-review-service.js +251 -0
- package/lib/auto/handoff-release-evidence-service.js +190 -0
- package/lib/auto/handoff-release-gate-history-loaders-service.js +502 -0
- package/lib/auto/handoff-release-gate-history-service.js +257 -0
- package/lib/auto/handoff-reporting-service.js +1407 -0
- package/lib/auto/handoff-run-service.js +486 -0
- package/lib/auto/handoff-snapshots-service.js +645 -0
- package/lib/auto/observability-service.js +132 -0
- package/lib/auto/output-writer.js +34 -0
- package/lib/auto/program-auto-remediation-service.js +130 -0
- package/lib/auto/program-diagnostics.js +138 -0
- package/lib/auto/program-governance-helpers.js +306 -0
- package/lib/auto/program-governance-loop-service.js +413 -0
- package/lib/auto/program-output.js +106 -0
- package/lib/auto/program-summary.js +183 -0
- package/lib/auto/recovery-memory-service.js +684 -0
- package/lib/auto/recovery-selection-service.js +52 -0
- package/lib/auto/retention-policy.js +98 -0
- package/lib/auto/session-persistence-service.js +106 -0
- package/lib/auto/session-presenter.js +105 -0
- package/lib/auto/session-prune-service.js +190 -0
- package/lib/auto/session-query-service.js +249 -0
- package/lib/auto/spec-protection.js +141 -0
- package/lib/commands/app.js +911 -0
- package/lib/commands/assurance.js +212 -0
- package/lib/commands/auto.js +1091 -11063
- package/lib/commands/mode.js +321 -0
- package/lib/commands/ontology.js +415 -0
- package/lib/commands/pm.js +422 -0
- package/lib/ontology/seed-profiles.js +160 -0
- package/lib/state/sce-state-store.js +3369 -1200
- package/package.json +1 -1
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
function normalizeHandoffText(value) {
|
|
2
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
function parseAutoHandoffGateBoolean(value, fallback = null) {
|
|
6
|
+
if (typeof value === 'boolean') {
|
|
7
|
+
return value;
|
|
8
|
+
}
|
|
9
|
+
const normalized = normalizeHandoffText(value).toLowerCase();
|
|
10
|
+
if (!normalized) {
|
|
11
|
+
return fallback;
|
|
12
|
+
}
|
|
13
|
+
if (['1', 'true', 'yes', 'y', 'on', 'passed', 'pass'].includes(normalized)) {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
if (['0', 'false', 'no', 'n', 'off', 'failed', 'fail', 'blocked'].includes(normalized)) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
return fallback;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function normalizeAutoHandoffGateRiskLevel(levelCandidate) {
|
|
23
|
+
const normalized = normalizeHandoffText(levelCandidate).toLowerCase();
|
|
24
|
+
if (!normalized) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
if (['low', 'medium', 'high', 'critical'].includes(normalized)) {
|
|
28
|
+
return normalized;
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function toGovernanceReleaseGateNumber(value) {
|
|
34
|
+
if (value === null || value === undefined || value === '') {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
const parsed = Number(value);
|
|
38
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function normalizeGovernanceReleaseGateSnapshot(snapshotCandidate) {
|
|
42
|
+
if (!snapshotCandidate || typeof snapshotCandidate !== 'object' || Array.isArray(snapshotCandidate)) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
available: snapshotCandidate.available === true,
|
|
47
|
+
latest_gate_passed: parseAutoHandoffGateBoolean(snapshotCandidate.latest_gate_passed, null),
|
|
48
|
+
pass_rate_percent: toGovernanceReleaseGateNumber(snapshotCandidate.pass_rate_percent),
|
|
49
|
+
scene_package_batch_pass_rate_percent: toGovernanceReleaseGateNumber(snapshotCandidate.scene_package_batch_pass_rate_percent),
|
|
50
|
+
drift_alert_rate_percent: toGovernanceReleaseGateNumber(snapshotCandidate.drift_alert_rate_percent),
|
|
51
|
+
drift_blocked_runs: toGovernanceReleaseGateNumber(snapshotCandidate.drift_blocked_runs)
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function normalizeGovernanceWeeklyOpsStopDetail(detailCandidate) {
|
|
56
|
+
if (!detailCandidate || typeof detailCandidate !== 'object' || Array.isArray(detailCandidate)) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
const latestCandidate = detailCandidate.latest && typeof detailCandidate.latest === 'object' ? detailCandidate.latest : {};
|
|
60
|
+
const aggregatesCandidate = detailCandidate.aggregates && typeof detailCandidate.aggregates === 'object' ? detailCandidate.aggregates : {};
|
|
61
|
+
const pressureCandidate = detailCandidate.pressure && typeof detailCandidate.pressure === 'object' ? detailCandidate.pressure : {};
|
|
62
|
+
|
|
63
|
+
const latestRiskLevelRaw = normalizeHandoffText(latestCandidate.risk_level);
|
|
64
|
+
const latestRiskLevel = latestRiskLevelRaw ? normalizeAutoHandoffGateRiskLevel(latestRiskLevelRaw) : null;
|
|
65
|
+
const normalized = {
|
|
66
|
+
latest: {
|
|
67
|
+
blocked: parseAutoHandoffGateBoolean(latestCandidate.blocked, null),
|
|
68
|
+
risk_level: latestRiskLevel,
|
|
69
|
+
governance_status: normalizeHandoffText(latestCandidate.governance_status),
|
|
70
|
+
authorization_tier_block_rate_percent: toGovernanceReleaseGateNumber(latestCandidate.authorization_tier_block_rate_percent),
|
|
71
|
+
dialogue_authorization_block_rate_percent: toGovernanceReleaseGateNumber(latestCandidate.dialogue_authorization_block_rate_percent),
|
|
72
|
+
config_warning_count: toGovernanceReleaseGateNumber(latestCandidate.config_warning_count),
|
|
73
|
+
runtime_block_rate_percent: toGovernanceReleaseGateNumber(latestCandidate.runtime_block_rate_percent),
|
|
74
|
+
runtime_ui_mode_violation_total: toGovernanceReleaseGateNumber(latestCandidate.runtime_ui_mode_violation_total),
|
|
75
|
+
runtime_ui_mode_violation_rate_percent: toGovernanceReleaseGateNumber(latestCandidate.runtime_ui_mode_violation_rate_percent)
|
|
76
|
+
},
|
|
77
|
+
aggregates: {
|
|
78
|
+
blocked_runs: toGovernanceReleaseGateNumber(aggregatesCandidate.blocked_runs),
|
|
79
|
+
block_rate_percent: toGovernanceReleaseGateNumber(aggregatesCandidate.block_rate_percent),
|
|
80
|
+
violations_total: toGovernanceReleaseGateNumber(aggregatesCandidate.violations_total),
|
|
81
|
+
warnings_total: toGovernanceReleaseGateNumber(aggregatesCandidate.warnings_total),
|
|
82
|
+
config_warnings_total: toGovernanceReleaseGateNumber(aggregatesCandidate.config_warnings_total),
|
|
83
|
+
authorization_tier_block_rate_max_percent: toGovernanceReleaseGateNumber(aggregatesCandidate.authorization_tier_block_rate_max_percent),
|
|
84
|
+
dialogue_authorization_block_rate_max_percent: toGovernanceReleaseGateNumber(aggregatesCandidate.dialogue_authorization_block_rate_max_percent),
|
|
85
|
+
runtime_block_rate_max_percent: toGovernanceReleaseGateNumber(aggregatesCandidate.runtime_block_rate_max_percent),
|
|
86
|
+
runtime_ui_mode_violation_total: toGovernanceReleaseGateNumber(aggregatesCandidate.runtime_ui_mode_violation_total),
|
|
87
|
+
runtime_ui_mode_violation_run_rate_percent: toGovernanceReleaseGateNumber(aggregatesCandidate.runtime_ui_mode_violation_run_rate_percent),
|
|
88
|
+
runtime_ui_mode_violation_rate_max_percent: toGovernanceReleaseGateNumber(aggregatesCandidate.runtime_ui_mode_violation_rate_max_percent)
|
|
89
|
+
},
|
|
90
|
+
pressure: {
|
|
91
|
+
blocked: parseAutoHandoffGateBoolean(pressureCandidate.blocked, null),
|
|
92
|
+
high: parseAutoHandoffGateBoolean(pressureCandidate.high, null),
|
|
93
|
+
config_warning_positive: parseAutoHandoffGateBoolean(pressureCandidate.config_warning_positive, null),
|
|
94
|
+
auth_tier_block_rate_high: parseAutoHandoffGateBoolean(pressureCandidate.auth_tier_block_rate_high, null),
|
|
95
|
+
dialogue_authorization_block_rate_high: parseAutoHandoffGateBoolean(pressureCandidate.dialogue_authorization_block_rate_high, null),
|
|
96
|
+
runtime_block_rate_high: parseAutoHandoffGateBoolean(pressureCandidate.runtime_block_rate_high, null),
|
|
97
|
+
runtime_ui_mode_violation_high: parseAutoHandoffGateBoolean(pressureCandidate.runtime_ui_mode_violation_high, null)
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
const hasSignal = (
|
|
101
|
+
typeof normalized.latest.blocked === 'boolean' ||
|
|
102
|
+
!!normalized.latest.risk_level ||
|
|
103
|
+
!!normalized.latest.governance_status ||
|
|
104
|
+
Number.isFinite(normalized.latest.authorization_tier_block_rate_percent) ||
|
|
105
|
+
Number.isFinite(normalized.latest.dialogue_authorization_block_rate_percent) ||
|
|
106
|
+
Number.isFinite(normalized.latest.config_warning_count) ||
|
|
107
|
+
Number.isFinite(normalized.latest.runtime_block_rate_percent) ||
|
|
108
|
+
Number.isFinite(normalized.latest.runtime_ui_mode_violation_total) ||
|
|
109
|
+
Number.isFinite(normalized.latest.runtime_ui_mode_violation_rate_percent) ||
|
|
110
|
+
Number.isFinite(normalized.aggregates.blocked_runs) ||
|
|
111
|
+
Number.isFinite(normalized.aggregates.block_rate_percent) ||
|
|
112
|
+
Number.isFinite(normalized.aggregates.violations_total) ||
|
|
113
|
+
Number.isFinite(normalized.aggregates.warnings_total) ||
|
|
114
|
+
Number.isFinite(normalized.aggregates.config_warnings_total) ||
|
|
115
|
+
Number.isFinite(normalized.aggregates.authorization_tier_block_rate_max_percent) ||
|
|
116
|
+
Number.isFinite(normalized.aggregates.dialogue_authorization_block_rate_max_percent) ||
|
|
117
|
+
Number.isFinite(normalized.aggregates.runtime_block_rate_max_percent) ||
|
|
118
|
+
Number.isFinite(normalized.aggregates.runtime_ui_mode_violation_total) ||
|
|
119
|
+
Number.isFinite(normalized.aggregates.runtime_ui_mode_violation_run_rate_percent) ||
|
|
120
|
+
Number.isFinite(normalized.aggregates.runtime_ui_mode_violation_rate_max_percent) ||
|
|
121
|
+
typeof normalized.pressure.blocked === 'boolean' ||
|
|
122
|
+
typeof normalized.pressure.high === 'boolean' ||
|
|
123
|
+
typeof normalized.pressure.config_warning_positive === 'boolean' ||
|
|
124
|
+
typeof normalized.pressure.auth_tier_block_rate_high === 'boolean' ||
|
|
125
|
+
typeof normalized.pressure.dialogue_authorization_block_rate_high === 'boolean' ||
|
|
126
|
+
typeof normalized.pressure.runtime_block_rate_high === 'boolean' ||
|
|
127
|
+
typeof normalized.pressure.runtime_ui_mode_violation_high === 'boolean'
|
|
128
|
+
);
|
|
129
|
+
return hasSignal ? normalized : null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
module.exports = {
|
|
133
|
+
normalizeHandoffText,
|
|
134
|
+
parseAutoHandoffGateBoolean,
|
|
135
|
+
normalizeAutoHandoffGateRiskLevel,
|
|
136
|
+
toGovernanceReleaseGateNumber,
|
|
137
|
+
normalizeGovernanceReleaseGateSnapshot,
|
|
138
|
+
normalizeGovernanceWeeklyOpsStopDetail
|
|
139
|
+
};
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
function presentGovernanceSessionStats(projectPath, filteredSessions, options = {}, dependencies = {}) {
|
|
2
|
+
const sessions = Array.isArray(filteredSessions) ? filteredSessions : [];
|
|
3
|
+
const normalizeStatusToken = dependencies.normalizeStatusToken || ((value) => String(value || '').trim().toLowerCase());
|
|
4
|
+
const isCompletedStatus = dependencies.isCompletedStatus || ((status) => normalizeStatusToken(status) === 'completed');
|
|
5
|
+
const isFailedStatus = dependencies.isFailedStatus || ((status) => ['failed', 'partial-failed', 'error', 'invalid'].includes(normalizeStatusToken(status)));
|
|
6
|
+
const calculatePercent = dependencies.calculatePercent || ((a, b) => (Number(b) > 0 ? Number(((Number(a) / Number(b)) * 100).toFixed(2)) : 0));
|
|
7
|
+
const toGovernanceReleaseGateNumber = dependencies.toGovernanceReleaseGateNumber || ((value) => {
|
|
8
|
+
if (value === null || value === undefined || value === '') {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
const parsed = Number(value);
|
|
12
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
13
|
+
});
|
|
14
|
+
const getGovernanceCloseLoopSessionDir = dependencies.getGovernanceCloseLoopSessionDir || ((value) => value);
|
|
15
|
+
const buildStatusCounts = dependencies.buildStatusCounts || (() => ({}));
|
|
16
|
+
const parseAutoHandoffGateBoolean = dependencies.parseAutoHandoffGateBoolean || ((value, fallback = null) => {
|
|
17
|
+
if (value === true) {
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
if (value === false) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
return fallback;
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const days = options.days ?? null;
|
|
27
|
+
const statusFilter = Array.isArray(options.status_filter) ? options.status_filter : [];
|
|
28
|
+
const resumeOnly = Boolean(options.resume_only);
|
|
29
|
+
const cutoffMs = options.cutoff_ms ?? null;
|
|
30
|
+
|
|
31
|
+
let completedSessions = 0;
|
|
32
|
+
let failedSessions = 0;
|
|
33
|
+
let stoppedSessions = 0;
|
|
34
|
+
let convergedSessions = 0;
|
|
35
|
+
let advisoryEnabledSessions = 0;
|
|
36
|
+
let advisoryFailedActionsSum = 0;
|
|
37
|
+
let performedRoundsSum = 0;
|
|
38
|
+
let sessionsWithRounds = 0;
|
|
39
|
+
let resumedSessions = 0;
|
|
40
|
+
let releaseGateObservedSessions = 0;
|
|
41
|
+
let releaseGateFailedSessions = 0;
|
|
42
|
+
let releaseGateDriftAlertSessions = 0;
|
|
43
|
+
let releaseGateBlockedSessions = 0;
|
|
44
|
+
let releaseGatePassRateSum = 0;
|
|
45
|
+
let releaseGatePassRateCount = 0;
|
|
46
|
+
let releaseGateSceneBatchPassRateSum = 0;
|
|
47
|
+
let releaseGateSceneBatchPassRateCount = 0;
|
|
48
|
+
let releaseGateDriftAlertRateSum = 0;
|
|
49
|
+
let releaseGateDriftAlertRateCount = 0;
|
|
50
|
+
let roundReleaseGateObservedSum = 0;
|
|
51
|
+
let roundReleaseGateChangedSum = 0;
|
|
52
|
+
let weeklyOpsStopSessions = 0;
|
|
53
|
+
let weeklyOpsBlockedStopSessions = 0;
|
|
54
|
+
let weeklyOpsHighPressureStopSessions = 0;
|
|
55
|
+
let weeklyOpsConfigWarningPositiveStopSessions = 0;
|
|
56
|
+
let weeklyOpsAuthTierPressureStopSessions = 0;
|
|
57
|
+
let weeklyOpsDialoguePressureStopSessions = 0;
|
|
58
|
+
let weeklyOpsRuntimeBlockRateHighStopSessions = 0;
|
|
59
|
+
let weeklyOpsRuntimeUiModeViolationHighStopSessions = 0;
|
|
60
|
+
let weeklyOpsBlockedRunsSum = 0;
|
|
61
|
+
let weeklyOpsBlockedRunsCount = 0;
|
|
62
|
+
let weeklyOpsBlockRateSum = 0;
|
|
63
|
+
let weeklyOpsBlockRateCount = 0;
|
|
64
|
+
let weeklyOpsConfigWarningsTotalSum = 0;
|
|
65
|
+
let weeklyOpsConfigWarningsTotalCount = 0;
|
|
66
|
+
let weeklyOpsAuthTierBlockRateSum = 0;
|
|
67
|
+
let weeklyOpsAuthTierBlockRateCount = 0;
|
|
68
|
+
let weeklyOpsDialogueBlockRateSum = 0;
|
|
69
|
+
let weeklyOpsDialogueBlockRateCount = 0;
|
|
70
|
+
let weeklyOpsRuntimeBlockRateSum = 0;
|
|
71
|
+
let weeklyOpsRuntimeBlockRateCount = 0;
|
|
72
|
+
let weeklyOpsRuntimeUiModeViolationTotalSum = 0;
|
|
73
|
+
let weeklyOpsRuntimeUiModeViolationTotalCount = 0;
|
|
74
|
+
let weeklyOpsRuntimeUiModeViolationRateSum = 0;
|
|
75
|
+
let weeklyOpsRuntimeUiModeViolationRateCount = 0;
|
|
76
|
+
const stopReasonCounts = {};
|
|
77
|
+
const finalRiskCounts = {};
|
|
78
|
+
const resumedFromCounts = {};
|
|
79
|
+
|
|
80
|
+
for (const session of sessions) {
|
|
81
|
+
const status = normalizeStatusToken(session && session.status) || 'unknown';
|
|
82
|
+
if (isCompletedStatus(status)) {
|
|
83
|
+
completedSessions += 1;
|
|
84
|
+
} else if (isFailedStatus(status)) {
|
|
85
|
+
failedSessions += 1;
|
|
86
|
+
} else if (status === 'stopped') {
|
|
87
|
+
stoppedSessions += 1;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (session && session.converged === true) {
|
|
91
|
+
convergedSessions += 1;
|
|
92
|
+
}
|
|
93
|
+
if (session && session.execute_advisory === true) {
|
|
94
|
+
advisoryEnabledSessions += 1;
|
|
95
|
+
}
|
|
96
|
+
advisoryFailedActionsSum += Number(session && session.advisory_failed_actions) || 0;
|
|
97
|
+
|
|
98
|
+
const performedRounds = Number(session && session.performed_rounds);
|
|
99
|
+
if (Number.isFinite(performedRounds)) {
|
|
100
|
+
performedRoundsSum += performedRounds;
|
|
101
|
+
sessionsWithRounds += 1;
|
|
102
|
+
}
|
|
103
|
+
if (session && session.resumed_from_governance_session_id) {
|
|
104
|
+
resumedSessions += 1;
|
|
105
|
+
const parentId = String(session.resumed_from_governance_session_id).trim() || 'unknown';
|
|
106
|
+
resumedFromCounts[parentId] = (resumedFromCounts[parentId] || 0) + 1;
|
|
107
|
+
}
|
|
108
|
+
if (session && session.release_gate_available === true) {
|
|
109
|
+
releaseGateObservedSessions += 1;
|
|
110
|
+
const latestGatePassed = parseAutoHandoffGateBoolean(session.release_gate_latest_gate_passed, null);
|
|
111
|
+
if (latestGatePassed === false) {
|
|
112
|
+
releaseGateFailedSessions += 1;
|
|
113
|
+
}
|
|
114
|
+
const releaseGatePassRate = Number(session.release_gate_pass_rate_percent);
|
|
115
|
+
if (Number.isFinite(releaseGatePassRate)) {
|
|
116
|
+
releaseGatePassRateSum += releaseGatePassRate;
|
|
117
|
+
releaseGatePassRateCount += 1;
|
|
118
|
+
}
|
|
119
|
+
const sceneBatchPassRate = Number(session.release_gate_scene_package_batch_pass_rate_percent);
|
|
120
|
+
if (Number.isFinite(sceneBatchPassRate)) {
|
|
121
|
+
releaseGateSceneBatchPassRateSum += sceneBatchPassRate;
|
|
122
|
+
releaseGateSceneBatchPassRateCount += 1;
|
|
123
|
+
}
|
|
124
|
+
const driftAlertRate = Number(session.release_gate_drift_alert_rate_percent);
|
|
125
|
+
if (Number.isFinite(driftAlertRate)) {
|
|
126
|
+
releaseGateDriftAlertRateSum += driftAlertRate;
|
|
127
|
+
releaseGateDriftAlertRateCount += 1;
|
|
128
|
+
if (driftAlertRate > 0) {
|
|
129
|
+
releaseGateDriftAlertSessions += 1;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const driftBlockedRuns = Number(session.release_gate_drift_blocked_runs);
|
|
133
|
+
if (Number.isFinite(driftBlockedRuns) && driftBlockedRuns > 0) {
|
|
134
|
+
releaseGateBlockedSessions += 1;
|
|
135
|
+
}
|
|
136
|
+
roundReleaseGateObservedSum += Number(session.round_release_gate_observed) || 0;
|
|
137
|
+
roundReleaseGateChangedSum += Number(session.round_release_gate_changed) || 0;
|
|
138
|
+
}
|
|
139
|
+
if (session && session.stop_detail_weekly_ops_available === true) {
|
|
140
|
+
weeklyOpsStopSessions += 1;
|
|
141
|
+
}
|
|
142
|
+
if (session && session.stop_detail_weekly_ops_blocked === true) {
|
|
143
|
+
weeklyOpsBlockedStopSessions += 1;
|
|
144
|
+
}
|
|
145
|
+
if (session && session.stop_detail_weekly_ops_high_pressure === true) {
|
|
146
|
+
weeklyOpsHighPressureStopSessions += 1;
|
|
147
|
+
}
|
|
148
|
+
if (session && session.stop_detail_weekly_ops_config_warning_positive === true) {
|
|
149
|
+
weeklyOpsConfigWarningPositiveStopSessions += 1;
|
|
150
|
+
}
|
|
151
|
+
if (session && session.stop_detail_weekly_ops_auth_tier_block_rate_high === true) {
|
|
152
|
+
weeklyOpsAuthTierPressureStopSessions += 1;
|
|
153
|
+
}
|
|
154
|
+
if (session && session.stop_detail_weekly_ops_dialogue_authorization_block_rate_high === true) {
|
|
155
|
+
weeklyOpsDialoguePressureStopSessions += 1;
|
|
156
|
+
}
|
|
157
|
+
if (session && session.stop_detail_weekly_ops_runtime_block_rate_high === true) {
|
|
158
|
+
weeklyOpsRuntimeBlockRateHighStopSessions += 1;
|
|
159
|
+
}
|
|
160
|
+
if (session && session.stop_detail_weekly_ops_runtime_ui_mode_violation_high === true) {
|
|
161
|
+
weeklyOpsRuntimeUiModeViolationHighStopSessions += 1;
|
|
162
|
+
}
|
|
163
|
+
const weeklyOpsBlockedRuns = toGovernanceReleaseGateNumber(session && session.stop_detail_weekly_ops_blocked_runs);
|
|
164
|
+
if (Number.isFinite(weeklyOpsBlockedRuns)) {
|
|
165
|
+
weeklyOpsBlockedRunsSum += weeklyOpsBlockedRuns;
|
|
166
|
+
weeklyOpsBlockedRunsCount += 1;
|
|
167
|
+
}
|
|
168
|
+
const weeklyOpsBlockRate = toGovernanceReleaseGateNumber(session && session.stop_detail_weekly_ops_block_rate_percent);
|
|
169
|
+
if (Number.isFinite(weeklyOpsBlockRate)) {
|
|
170
|
+
weeklyOpsBlockRateSum += weeklyOpsBlockRate;
|
|
171
|
+
weeklyOpsBlockRateCount += 1;
|
|
172
|
+
}
|
|
173
|
+
const weeklyOpsConfigWarningsTotal = toGovernanceReleaseGateNumber(session && session.stop_detail_weekly_ops_config_warnings_total);
|
|
174
|
+
if (Number.isFinite(weeklyOpsConfigWarningsTotal)) {
|
|
175
|
+
weeklyOpsConfigWarningsTotalSum += weeklyOpsConfigWarningsTotal;
|
|
176
|
+
weeklyOpsConfigWarningsTotalCount += 1;
|
|
177
|
+
}
|
|
178
|
+
const weeklyOpsAuthTierBlockRate = toGovernanceReleaseGateNumber(session && session.stop_detail_weekly_ops_auth_tier_block_rate_percent);
|
|
179
|
+
if (Number.isFinite(weeklyOpsAuthTierBlockRate)) {
|
|
180
|
+
weeklyOpsAuthTierBlockRateSum += weeklyOpsAuthTierBlockRate;
|
|
181
|
+
weeklyOpsAuthTierBlockRateCount += 1;
|
|
182
|
+
}
|
|
183
|
+
const weeklyOpsDialogueBlockRate = toGovernanceReleaseGateNumber(session && session.stop_detail_weekly_ops_dialogue_authorization_block_rate_percent);
|
|
184
|
+
if (Number.isFinite(weeklyOpsDialogueBlockRate)) {
|
|
185
|
+
weeklyOpsDialogueBlockRateSum += weeklyOpsDialogueBlockRate;
|
|
186
|
+
weeklyOpsDialogueBlockRateCount += 1;
|
|
187
|
+
}
|
|
188
|
+
const weeklyOpsRuntimeBlockRate = toGovernanceReleaseGateNumber(session && session.stop_detail_weekly_ops_runtime_block_rate_percent);
|
|
189
|
+
if (Number.isFinite(weeklyOpsRuntimeBlockRate)) {
|
|
190
|
+
weeklyOpsRuntimeBlockRateSum += weeklyOpsRuntimeBlockRate;
|
|
191
|
+
weeklyOpsRuntimeBlockRateCount += 1;
|
|
192
|
+
}
|
|
193
|
+
const weeklyOpsRuntimeUiModeViolationTotal = toGovernanceReleaseGateNumber(session && session.stop_detail_weekly_ops_runtime_ui_mode_violation_total);
|
|
194
|
+
if (Number.isFinite(weeklyOpsRuntimeUiModeViolationTotal)) {
|
|
195
|
+
weeklyOpsRuntimeUiModeViolationTotalSum += weeklyOpsRuntimeUiModeViolationTotal;
|
|
196
|
+
weeklyOpsRuntimeUiModeViolationTotalCount += 1;
|
|
197
|
+
}
|
|
198
|
+
const weeklyOpsRuntimeUiModeViolationRate = toGovernanceReleaseGateNumber(session && session.stop_detail_weekly_ops_runtime_ui_mode_violation_rate_percent);
|
|
199
|
+
if (Number.isFinite(weeklyOpsRuntimeUiModeViolationRate)) {
|
|
200
|
+
weeklyOpsRuntimeUiModeViolationRateSum += weeklyOpsRuntimeUiModeViolationRate;
|
|
201
|
+
weeklyOpsRuntimeUiModeViolationRateCount += 1;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const stopReason = String(session && session.stop_reason ? session.stop_reason : '').trim().toLowerCase() || 'unknown';
|
|
205
|
+
stopReasonCounts[stopReason] = (stopReasonCounts[stopReason] || 0) + 1;
|
|
206
|
+
|
|
207
|
+
const finalRisk = String(session && session.final_risk ? session.final_risk : '').trim().toLowerCase() || 'unknown';
|
|
208
|
+
finalRiskCounts[finalRisk] = (finalRiskCounts[finalRisk] || 0) + 1;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const totalSessions = sessions.length;
|
|
212
|
+
const completionRate = totalSessions > 0 ? Number(((completedSessions / totalSessions) * 100).toFixed(2)) : 0;
|
|
213
|
+
const failureRate = totalSessions > 0 ? Number(((failedSessions / totalSessions) * 100).toFixed(2)) : 0;
|
|
214
|
+
const averagePerformedRounds = sessionsWithRounds > 0 ? Number((performedRoundsSum / sessionsWithRounds).toFixed(2)) : 0;
|
|
215
|
+
const resumedRate = totalSessions > 0 ? Number(((resumedSessions / totalSessions) * 100).toFixed(2)) : 0;
|
|
216
|
+
const latestSession = totalSessions > 0 ? sessions[0] : null;
|
|
217
|
+
const oldestSession = totalSessions > 0 ? sessions[sessions.length - 1] : null;
|
|
218
|
+
|
|
219
|
+
return {
|
|
220
|
+
mode: 'auto-governance-session-stats',
|
|
221
|
+
session_dir: getGovernanceCloseLoopSessionDir(projectPath),
|
|
222
|
+
criteria: {
|
|
223
|
+
days,
|
|
224
|
+
status_filter: statusFilter,
|
|
225
|
+
resume_only: resumeOnly,
|
|
226
|
+
since: cutoffMs === null ? null : new Date(cutoffMs).toISOString()
|
|
227
|
+
},
|
|
228
|
+
total_sessions: totalSessions,
|
|
229
|
+
resumed_sessions: resumedSessions,
|
|
230
|
+
fresh_sessions: totalSessions - resumedSessions,
|
|
231
|
+
resumed_rate_percent: resumedRate,
|
|
232
|
+
completed_sessions: completedSessions,
|
|
233
|
+
failed_sessions: failedSessions,
|
|
234
|
+
stopped_sessions: stoppedSessions,
|
|
235
|
+
converged_sessions: convergedSessions,
|
|
236
|
+
advisory_enabled_sessions: advisoryEnabledSessions,
|
|
237
|
+
advisory_failed_actions_sum: advisoryFailedActionsSum,
|
|
238
|
+
completion_rate_percent: completionRate,
|
|
239
|
+
failure_rate_percent: failureRate,
|
|
240
|
+
average_performed_rounds: averagePerformedRounds,
|
|
241
|
+
release_gate: {
|
|
242
|
+
observed_sessions: releaseGateObservedSessions,
|
|
243
|
+
failed_sessions: releaseGateFailedSessions,
|
|
244
|
+
failed_rate_percent: calculatePercent(releaseGateFailedSessions, releaseGateObservedSessions),
|
|
245
|
+
drift_alert_sessions: releaseGateDriftAlertSessions,
|
|
246
|
+
drift_alert_session_rate_percent: calculatePercent(releaseGateDriftAlertSessions, releaseGateObservedSessions),
|
|
247
|
+
blocked_sessions: releaseGateBlockedSessions,
|
|
248
|
+
average_pass_rate_percent: releaseGatePassRateCount > 0 ? Number((releaseGatePassRateSum / releaseGatePassRateCount).toFixed(2)) : null,
|
|
249
|
+
average_scene_package_batch_pass_rate_percent: releaseGateSceneBatchPassRateCount > 0 ? Number((releaseGateSceneBatchPassRateSum / releaseGateSceneBatchPassRateCount).toFixed(2)) : null,
|
|
250
|
+
average_drift_alert_rate_percent: releaseGateDriftAlertRateCount > 0 ? Number((releaseGateDriftAlertRateSum / releaseGateDriftAlertRateCount).toFixed(2)) : null,
|
|
251
|
+
round_telemetry_observed: roundReleaseGateObservedSum,
|
|
252
|
+
round_telemetry_changed: roundReleaseGateChangedSum,
|
|
253
|
+
round_telemetry_change_rate_percent: calculatePercent(roundReleaseGateChangedSum, roundReleaseGateObservedSum),
|
|
254
|
+
weekly_ops_stop: {
|
|
255
|
+
sessions: weeklyOpsStopSessions,
|
|
256
|
+
session_rate_percent: calculatePercent(weeklyOpsStopSessions, totalSessions),
|
|
257
|
+
blocked_sessions: weeklyOpsBlockedStopSessions,
|
|
258
|
+
blocked_session_rate_percent: calculatePercent(weeklyOpsBlockedStopSessions, weeklyOpsStopSessions),
|
|
259
|
+
high_pressure_sessions: weeklyOpsHighPressureStopSessions,
|
|
260
|
+
high_pressure_session_rate_percent: calculatePercent(weeklyOpsHighPressureStopSessions, weeklyOpsStopSessions),
|
|
261
|
+
config_warning_positive_sessions: weeklyOpsConfigWarningPositiveStopSessions,
|
|
262
|
+
config_warning_positive_rate_percent: calculatePercent(weeklyOpsConfigWarningPositiveStopSessions, weeklyOpsStopSessions),
|
|
263
|
+
auth_tier_pressure_sessions: weeklyOpsAuthTierPressureStopSessions,
|
|
264
|
+
auth_tier_pressure_rate_percent: calculatePercent(weeklyOpsAuthTierPressureStopSessions, weeklyOpsStopSessions),
|
|
265
|
+
dialogue_authorization_pressure_sessions: weeklyOpsDialoguePressureStopSessions,
|
|
266
|
+
dialogue_authorization_pressure_rate_percent: calculatePercent(weeklyOpsDialoguePressureStopSessions, weeklyOpsStopSessions),
|
|
267
|
+
runtime_block_rate_high_sessions: weeklyOpsRuntimeBlockRateHighStopSessions,
|
|
268
|
+
runtime_block_rate_high_rate_percent: calculatePercent(weeklyOpsRuntimeBlockRateHighStopSessions, weeklyOpsStopSessions),
|
|
269
|
+
runtime_ui_mode_violation_high_sessions: weeklyOpsRuntimeUiModeViolationHighStopSessions,
|
|
270
|
+
runtime_ui_mode_violation_high_rate_percent: calculatePercent(weeklyOpsRuntimeUiModeViolationHighStopSessions, weeklyOpsStopSessions),
|
|
271
|
+
blocked_runs_sum: weeklyOpsBlockedRunsSum,
|
|
272
|
+
average_blocked_runs: weeklyOpsBlockedRunsCount > 0 ? Number((weeklyOpsBlockedRunsSum / weeklyOpsBlockedRunsCount).toFixed(2)) : null,
|
|
273
|
+
average_block_rate_percent: weeklyOpsBlockRateCount > 0 ? Number((weeklyOpsBlockRateSum / weeklyOpsBlockRateCount).toFixed(2)) : null,
|
|
274
|
+
config_warnings_total_sum: weeklyOpsConfigWarningsTotalSum,
|
|
275
|
+
average_config_warnings_total: weeklyOpsConfigWarningsTotalCount > 0 ? Number((weeklyOpsConfigWarningsTotalSum / weeklyOpsConfigWarningsTotalCount).toFixed(2)) : null,
|
|
276
|
+
average_auth_tier_block_rate_percent: weeklyOpsAuthTierBlockRateCount > 0 ? Number((weeklyOpsAuthTierBlockRateSum / weeklyOpsAuthTierBlockRateCount).toFixed(2)) : null,
|
|
277
|
+
average_dialogue_authorization_block_rate_percent: weeklyOpsDialogueBlockRateCount > 0 ? Number((weeklyOpsDialogueBlockRateSum / weeklyOpsDialogueBlockRateCount).toFixed(2)) : null,
|
|
278
|
+
average_runtime_block_rate_percent: weeklyOpsRuntimeBlockRateCount > 0 ? Number((weeklyOpsRuntimeBlockRateSum / weeklyOpsRuntimeBlockRateCount).toFixed(2)) : null,
|
|
279
|
+
runtime_ui_mode_violation_total_sum: weeklyOpsRuntimeUiModeViolationTotalSum,
|
|
280
|
+
average_runtime_ui_mode_violation_total: weeklyOpsRuntimeUiModeViolationTotalCount > 0 ? Number((weeklyOpsRuntimeUiModeViolationTotalSum / weeklyOpsRuntimeUiModeViolationTotalCount).toFixed(2)) : null,
|
|
281
|
+
average_runtime_ui_mode_violation_rate_percent: weeklyOpsRuntimeUiModeViolationRateCount > 0 ? Number((weeklyOpsRuntimeUiModeViolationRateSum / weeklyOpsRuntimeUiModeViolationRateCount).toFixed(2)) : null
|
|
282
|
+
}
|
|
283
|
+
},
|
|
284
|
+
status_counts: buildStatusCounts(sessions),
|
|
285
|
+
stop_reason_counts: stopReasonCounts,
|
|
286
|
+
final_risk_counts: finalRiskCounts,
|
|
287
|
+
resumed_from_counts: resumedFromCounts,
|
|
288
|
+
latest_updated_at: latestSession ? latestSession.updated_at : null,
|
|
289
|
+
oldest_updated_at: oldestSession ? oldestSession.updated_at : null,
|
|
290
|
+
latest_sessions: sessions.slice(0, 10).map((item) => ({
|
|
291
|
+
id: item.id,
|
|
292
|
+
status: item.status,
|
|
293
|
+
target_risk: item.target_risk,
|
|
294
|
+
final_risk: item.final_risk,
|
|
295
|
+
performed_rounds: item.performed_rounds,
|
|
296
|
+
max_rounds: item.max_rounds,
|
|
297
|
+
converged: item.converged,
|
|
298
|
+
execute_advisory: item.execute_advisory,
|
|
299
|
+
advisory_failed_actions: item.advisory_failed_actions,
|
|
300
|
+
release_gate_available: item.release_gate_available,
|
|
301
|
+
release_gate_latest_gate_passed: item.release_gate_latest_gate_passed,
|
|
302
|
+
release_gate_pass_rate_percent: item.release_gate_pass_rate_percent,
|
|
303
|
+
release_gate_drift_alert_rate_percent: item.release_gate_drift_alert_rate_percent,
|
|
304
|
+
round_release_gate_observed: item.round_release_gate_observed,
|
|
305
|
+
round_release_gate_changed: item.round_release_gate_changed,
|
|
306
|
+
stop_detail_weekly_ops_available: item.stop_detail_weekly_ops_available,
|
|
307
|
+
stop_detail_weekly_ops_blocked: item.stop_detail_weekly_ops_blocked,
|
|
308
|
+
stop_detail_weekly_ops_high_pressure: item.stop_detail_weekly_ops_high_pressure,
|
|
309
|
+
stop_detail_weekly_ops_config_warning_positive: item.stop_detail_weekly_ops_config_warning_positive,
|
|
310
|
+
stop_detail_weekly_ops_auth_tier_block_rate_high: item.stop_detail_weekly_ops_auth_tier_block_rate_high,
|
|
311
|
+
stop_detail_weekly_ops_dialogue_authorization_block_rate_high:
|
|
312
|
+
item.stop_detail_weekly_ops_dialogue_authorization_block_rate_high,
|
|
313
|
+
stop_detail_weekly_ops_runtime_block_rate_high: item.stop_detail_weekly_ops_runtime_block_rate_high,
|
|
314
|
+
stop_detail_weekly_ops_runtime_ui_mode_violation_high:
|
|
315
|
+
item.stop_detail_weekly_ops_runtime_ui_mode_violation_high,
|
|
316
|
+
stop_detail_weekly_ops_blocked_runs: item.stop_detail_weekly_ops_blocked_runs,
|
|
317
|
+
stop_detail_weekly_ops_block_rate_percent: item.stop_detail_weekly_ops_block_rate_percent,
|
|
318
|
+
stop_detail_weekly_ops_config_warnings_total: item.stop_detail_weekly_ops_config_warnings_total,
|
|
319
|
+
stop_detail_weekly_ops_auth_tier_block_rate_percent: item.stop_detail_weekly_ops_auth_tier_block_rate_percent,
|
|
320
|
+
stop_detail_weekly_ops_dialogue_authorization_block_rate_percent:
|
|
321
|
+
item.stop_detail_weekly_ops_dialogue_authorization_block_rate_percent,
|
|
322
|
+
stop_detail_weekly_ops_runtime_block_rate_percent: item.stop_detail_weekly_ops_runtime_block_rate_percent,
|
|
323
|
+
stop_detail_weekly_ops_runtime_ui_mode_violation_total:
|
|
324
|
+
item.stop_detail_weekly_ops_runtime_ui_mode_violation_total,
|
|
325
|
+
stop_detail_weekly_ops_runtime_ui_mode_violation_rate_percent:
|
|
326
|
+
item.stop_detail_weekly_ops_runtime_ui_mode_violation_rate_percent,
|
|
327
|
+
stop_reason: item.stop_reason,
|
|
328
|
+
resumed_from_governance_session_id: item.resumed_from_governance_session_id,
|
|
329
|
+
updated_at: item.updated_at,
|
|
330
|
+
parse_error: item.parse_error
|
|
331
|
+
}))
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
module.exports = {
|
|
336
|
+
presentGovernanceSessionStats
|
|
337
|
+
};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
async function buildAutoGovernanceStats(projectPath, options = {}, dependencies = {}) {
|
|
2
|
+
const {
|
|
3
|
+
normalizeStatsWindowDays,
|
|
4
|
+
normalizeStatusFilter,
|
|
5
|
+
statsCloseLoopSessions,
|
|
6
|
+
statsCloseLoopBatchSummarySessions,
|
|
7
|
+
statsCloseLoopControllerSessions,
|
|
8
|
+
showCloseLoopRecoveryMemory,
|
|
9
|
+
loadGovernanceReleaseGateSignals,
|
|
10
|
+
loadGovernanceHandoffQualitySignals,
|
|
11
|
+
calculatePercent,
|
|
12
|
+
deriveGovernanceRiskLevel,
|
|
13
|
+
buildGovernanceConcerns,
|
|
14
|
+
buildGovernanceRecommendations,
|
|
15
|
+
buildTopCountEntries,
|
|
16
|
+
now = () => new Date()
|
|
17
|
+
} = dependencies;
|
|
18
|
+
|
|
19
|
+
const days = normalizeStatsWindowDays(options.days);
|
|
20
|
+
const statusFilter = normalizeStatusFilter(options.status);
|
|
21
|
+
const normalizedOptions = {
|
|
22
|
+
days,
|
|
23
|
+
status: statusFilter.length > 0 ? statusFilter.join(',') : undefined
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const [sessionStats, batchStats, controllerStats, recoveryMemory, releaseGateSignals, handoffQualitySignals] = await Promise.all([
|
|
27
|
+
statsCloseLoopSessions(projectPath, normalizedOptions),
|
|
28
|
+
statsCloseLoopBatchSummarySessions(projectPath, normalizedOptions),
|
|
29
|
+
statsCloseLoopControllerSessions(projectPath, normalizedOptions),
|
|
30
|
+
showCloseLoopRecoveryMemory(projectPath, {}),
|
|
31
|
+
loadGovernanceReleaseGateSignals(projectPath),
|
|
32
|
+
loadGovernanceHandoffQualitySignals(projectPath)
|
|
33
|
+
]);
|
|
34
|
+
|
|
35
|
+
const totalSessions =
|
|
36
|
+
(Number(sessionStats.total_sessions) || 0) +
|
|
37
|
+
(Number(batchStats.total_sessions) || 0) +
|
|
38
|
+
(Number(controllerStats.total_sessions) || 0);
|
|
39
|
+
const completedSessions =
|
|
40
|
+
(Number(sessionStats.completed_sessions) || 0) +
|
|
41
|
+
(Number(batchStats.completed_sessions) || 0) +
|
|
42
|
+
(Number(controllerStats.completed_sessions) || 0);
|
|
43
|
+
const failedSessions =
|
|
44
|
+
(Number(sessionStats.failed_sessions) || 0) +
|
|
45
|
+
(Number(batchStats.failed_sessions) || 0) +
|
|
46
|
+
(Number(controllerStats.failed_sessions) || 0);
|
|
47
|
+
const pendingGoalsSum = Number(controllerStats.pending_goals_sum) || 0;
|
|
48
|
+
const recoverySignatureCount = Number(recoveryMemory && recoveryMemory.stats && recoveryMemory.stats.signature_count) || 0;
|
|
49
|
+
const summary = {
|
|
50
|
+
total_sessions: totalSessions,
|
|
51
|
+
completed_sessions: completedSessions,
|
|
52
|
+
failed_sessions: failedSessions,
|
|
53
|
+
failure_rate_percent: calculatePercent(failedSessions, totalSessions),
|
|
54
|
+
completion_rate_percent: calculatePercent(completedSessions, totalSessions),
|
|
55
|
+
pending_goals_sum: pendingGoalsSum,
|
|
56
|
+
recovery_signature_count: recoverySignatureCount,
|
|
57
|
+
release_gate: releaseGateSignals,
|
|
58
|
+
handoff_quality: handoffQualitySignals
|
|
59
|
+
};
|
|
60
|
+
const riskLevel = deriveGovernanceRiskLevel(summary);
|
|
61
|
+
const concerns = buildGovernanceConcerns(summary);
|
|
62
|
+
const recommendations = buildGovernanceRecommendations({
|
|
63
|
+
...summary,
|
|
64
|
+
risk_level: riskLevel
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
mode: 'auto-governance-stats',
|
|
69
|
+
generated_at: new Date().toISOString(),
|
|
70
|
+
criteria: {
|
|
71
|
+
days,
|
|
72
|
+
status_filter: statusFilter,
|
|
73
|
+
since: days === null
|
|
74
|
+
? null
|
|
75
|
+
: new Date(Date.now() - (days * 24 * 60 * 60 * 1000)).toISOString()
|
|
76
|
+
},
|
|
77
|
+
totals: {
|
|
78
|
+
total_sessions: totalSessions,
|
|
79
|
+
completed_sessions: completedSessions,
|
|
80
|
+
failed_sessions: failedSessions,
|
|
81
|
+
completion_rate_percent: summary.completion_rate_percent,
|
|
82
|
+
failure_rate_percent: summary.failure_rate_percent
|
|
83
|
+
},
|
|
84
|
+
throughput: {
|
|
85
|
+
sub_spec_count_sum: Number(sessionStats.sub_spec_count_sum) || 0,
|
|
86
|
+
batch_total_goals_sum: Number(batchStats.total_goals_sum) || 0,
|
|
87
|
+
batch_processed_goals_sum: Number(batchStats.processed_goals_sum) || 0,
|
|
88
|
+
controller_processed_goals_sum: Number(controllerStats.processed_goals_sum) || 0,
|
|
89
|
+
controller_pending_goals_sum: pendingGoalsSum
|
|
90
|
+
},
|
|
91
|
+
top_master_specs: buildTopCountEntries(sessionStats.master_spec_counts, 10),
|
|
92
|
+
health: {
|
|
93
|
+
risk_level: riskLevel,
|
|
94
|
+
concerns,
|
|
95
|
+
recommendations,
|
|
96
|
+
release_gate: releaseGateSignals,
|
|
97
|
+
handoff_quality: handoffQualitySignals
|
|
98
|
+
},
|
|
99
|
+
recovery_memory: {
|
|
100
|
+
file: recoveryMemory.file,
|
|
101
|
+
scope: recoveryMemory.scope,
|
|
102
|
+
signature_count: recoverySignatureCount,
|
|
103
|
+
action_count: Number(recoveryMemory && recoveryMemory.stats && recoveryMemory.stats.action_count) || 0
|
|
104
|
+
},
|
|
105
|
+
archives: {
|
|
106
|
+
session: sessionStats,
|
|
107
|
+
batch_session: batchStats,
|
|
108
|
+
controller_session: controllerStats
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
module.exports = {
|
|
114
|
+
buildAutoGovernanceStats
|
|
115
|
+
};
|