@sovr/engine 3.5.0 → 3.7.0

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/dist/index.js CHANGED
@@ -23,6 +23,7 @@ __export(index_exports, {
23
23
  AdaptiveThresholdManager: () => AdaptiveThresholdManager,
24
24
  AutoHardenEngine: () => AutoHardenEngine,
25
25
  ContextAccelerator: () => ContextAccelerator,
26
+ ContributionSettlementEngine: () => ContributionSettlementEngine,
26
27
  CostGateEnhancedEngine: () => CostGateEnhancedEngine,
27
28
  DEFAULT_CA_CONFIG: () => DEFAULT_CA_CONFIG,
28
29
  DEFAULT_GE_CONFIG: () => DEFAULT_GE_CONFIG,
@@ -34,12 +35,16 @@ __export(index_exports, {
34
35
  FeatureSwitchesManager: () => FeatureSwitchesManager,
35
36
  GovernanceEnhancer: () => GovernanceEnhancer,
36
37
  MultiLevelBudgetEngine: () => MultiLevelBudgetEngine,
38
+ OverrideDriftAnalyzer: () => OverrideDriftAnalyzer,
37
39
  PolicyEngine: () => PolicyEngine,
38
40
  PricingRulesEngine: () => PricingRulesEngine,
39
41
  RecalculationEngine: () => RecalculationEngine,
40
42
  SOVR_FEATURE_SWITCHES: () => SOVR_FEATURE_SWITCHES,
43
+ SelfConstraintEngine: () => SelfConstraintEngine,
41
44
  SemanticDriftDetectorEngine: () => SemanticDriftDetectorEngine,
45
+ TIME_WINDOWS: () => TIME_WINDOWS,
42
46
  TimeSeriesAggregator: () => TimeSeriesAggregator,
47
+ TrendAlertEngine: () => TrendAlertEngine,
43
48
  TwoPhaseRouter: () => TwoPhaseRouter,
44
49
  ValuationModel: () => ValuationModel,
45
50
  compileFromJSON: () => compileFromJSON,
@@ -3264,6 +3269,1118 @@ var ContextAccelerator = class {
3264
3269
  }
3265
3270
  };
3266
3271
 
3272
+ // src/trendAlertEngine.ts
3273
+ var DEFAULT_THRESHOLDS2 = [
3274
+ {
3275
+ alert_type: "BLOCK_RATE_SURGE",
3276
+ metric_name: "block_rate",
3277
+ baseline_window_hours: 24,
3278
+ surge_multiplier: 2,
3279
+ absolute_threshold: 0.5,
3280
+ severity: "CRITICAL",
3281
+ protective_actions: ["TIGHTEN_THRESHOLD", "NOTIFY_ONLY"],
3282
+ cooldown_seconds: 300,
3283
+ enabled: true
3284
+ },
3285
+ {
3286
+ alert_type: "OVERRIDE_RATE_SURGE",
3287
+ metric_name: "override_rate",
3288
+ baseline_window_hours: 24,
3289
+ surge_multiplier: 3,
3290
+ absolute_threshold: 0.3,
3291
+ severity: "CRITICAL",
3292
+ protective_actions: ["TIGHTEN_THRESHOLD", "FORCE_HUMAN_GATE"],
3293
+ cooldown_seconds: 300,
3294
+ enabled: true
3295
+ },
3296
+ {
3297
+ alert_type: "UNKNOWN_REASON_CODE",
3298
+ metric_name: "unknown_reason_rate",
3299
+ baseline_window_hours: 1,
3300
+ surge_multiplier: 1.5,
3301
+ absolute_threshold: 0.1,
3302
+ severity: "WARN",
3303
+ protective_actions: ["NOTIFY_ONLY"],
3304
+ cooldown_seconds: 600,
3305
+ enabled: true
3306
+ },
3307
+ {
3308
+ alert_type: "APPROVAL_QUEUE_BACKLOG",
3309
+ metric_name: "pending_approval_count",
3310
+ baseline_window_hours: 1,
3311
+ surge_multiplier: 5,
3312
+ absolute_threshold: 50,
3313
+ severity: "CRITICAL",
3314
+ protective_actions: ["DEGRADE", "NOTIFY_ONLY"],
3315
+ cooldown_seconds: 180,
3316
+ enabled: true
3317
+ },
3318
+ {
3319
+ alert_type: "CONFIDENCE_DROP",
3320
+ metric_name: "avg_confidence",
3321
+ baseline_window_hours: 24,
3322
+ surge_multiplier: 0.5,
3323
+ // 低于基线的比例
3324
+ absolute_threshold: 0.3,
3325
+ severity: "WARN",
3326
+ protective_actions: ["TIGHTEN_THRESHOLD"],
3327
+ cooldown_seconds: 600,
3328
+ enabled: true
3329
+ },
3330
+ {
3331
+ alert_type: "ERROR_RATE_SURGE",
3332
+ metric_name: "error_rate",
3333
+ baseline_window_hours: 1,
3334
+ surge_multiplier: 3,
3335
+ absolute_threshold: 0.2,
3336
+ severity: "EMERGENCY",
3337
+ protective_actions: ["KILL_SWITCH"],
3338
+ cooldown_seconds: 60,
3339
+ enabled: true
3340
+ }
3341
+ ];
3342
+ var TrendAlertEngine = class {
3343
+ thresholds;
3344
+ alertHistory = [];
3345
+ lastAlertTime = /* @__PURE__ */ new Map();
3346
+ systemState;
3347
+ metricsBuffer = [];
3348
+ constructor(customThresholds) {
3349
+ this.thresholds = customThresholds || DEFAULT_THRESHOLDS2;
3350
+ this.systemState = {
3351
+ kill_switch: { enabled: false, reason: null, enabled_at: null, enabled_by: "system", auto_triggered: false },
3352
+ degrade: { active: false, level: "LIGHT", reason: "", activated_at: null, auto_recover_at: null },
3353
+ tightened_threshold_multiplier: 1,
3354
+ force_human_gate: false
3355
+ };
3356
+ }
3357
+ // ---- 核心: 评估趋势 ----
3358
+ evaluate(metrics, tenantId = "default") {
3359
+ const alerts = [];
3360
+ this.metricsBuffer = metrics;
3361
+ for (const threshold of this.thresholds) {
3362
+ if (!threshold.enabled) continue;
3363
+ const metric = metrics.find((m) => m.metric_name === threshold.metric_name);
3364
+ if (!metric) continue;
3365
+ const lastAlert = this.lastAlertTime.get(threshold.alert_type);
3366
+ if (lastAlert && Date.now() - lastAlert < threshold.cooldown_seconds * 1e3) {
3367
+ continue;
3368
+ }
3369
+ const triggered = this.checkThreshold(metric, threshold);
3370
+ if (!triggered) continue;
3371
+ const surgeRatio = metric.baseline_value > 0 ? metric.current_value / metric.baseline_value : metric.current_value;
3372
+ const alert = {
3373
+ alert_id: `alert_${threshold.alert_type}_${Date.now()}`,
3374
+ alert_type: threshold.alert_type,
3375
+ severity: threshold.severity,
3376
+ metric_name: threshold.metric_name,
3377
+ current_value: metric.current_value,
3378
+ baseline_value: metric.baseline_value,
3379
+ threshold_value: threshold.absolute_threshold,
3380
+ surge_ratio: Math.round(surgeRatio * 100) / 100,
3381
+ protective_actions_taken: [],
3382
+ message: this.formatAlertMessage(threshold, metric, surgeRatio),
3383
+ tenant_id: tenantId,
3384
+ created_at: Date.now(),
3385
+ acknowledged: false,
3386
+ acknowledged_by: null,
3387
+ acknowledged_at: null
3388
+ };
3389
+ for (const action of threshold.protective_actions) {
3390
+ this.executeProtectiveAction(action, alert);
3391
+ alert.protective_actions_taken.push(action);
3392
+ }
3393
+ alerts.push(alert);
3394
+ this.alertHistory.push(alert);
3395
+ this.lastAlertTime.set(threshold.alert_type, Date.now());
3396
+ }
3397
+ return alerts;
3398
+ }
3399
+ // ---- Cron 评估入口 (DegradeEvaluator) ----
3400
+ cronEvaluate(getMetrics, tenantId = "default") {
3401
+ const metrics = getMetrics();
3402
+ const alerts = this.evaluate(metrics, tenantId);
3403
+ this.checkAutoRecover();
3404
+ return { alerts, state: this.getSystemState() };
3405
+ }
3406
+ // ---- 保护动作执行 ----
3407
+ executeProtectiveAction(action, alert) {
3408
+ switch (action) {
3409
+ case "DEGRADE":
3410
+ this.activateDegrade(alert);
3411
+ break;
3412
+ case "TIGHTEN_THRESHOLD":
3413
+ this.tightenThreshold(alert);
3414
+ break;
3415
+ case "KILL_SWITCH":
3416
+ this.activateKillSwitch(alert);
3417
+ break;
3418
+ case "FORCE_HUMAN_GATE":
3419
+ this.systemState.force_human_gate = true;
3420
+ break;
3421
+ case "NOTIFY_ONLY":
3422
+ break;
3423
+ }
3424
+ }
3425
+ activateDegrade(alert) {
3426
+ const level = alert.severity === "EMERGENCY" ? "SEVERE" : alert.severity === "CRITICAL" ? "MODERATE" : "LIGHT";
3427
+ this.systemState.degrade = {
3428
+ active: true,
3429
+ level,
3430
+ reason: `Auto-degrade triggered by ${alert.alert_type}: ${alert.message}`,
3431
+ activated_at: Date.now(),
3432
+ auto_recover_at: Date.now() + 30 * 60 * 1e3
3433
+ // 30分钟后自动恢复
3434
+ };
3435
+ }
3436
+ tightenThreshold(alert) {
3437
+ this.systemState.tightened_threshold_multiplier = Math.min(
3438
+ this.systemState.tightened_threshold_multiplier * 1.2,
3439
+ 2
3440
+ );
3441
+ }
3442
+ activateKillSwitch(alert) {
3443
+ this.systemState.kill_switch = {
3444
+ enabled: true,
3445
+ reason: `Auto Kill-Switch triggered by ${alert.alert_type}: ${alert.message}`,
3446
+ enabled_at: Date.now(),
3447
+ enabled_by: "trend_alert_engine",
3448
+ auto_triggered: true
3449
+ };
3450
+ }
3451
+ // ---- 阈值检查 ----
3452
+ checkThreshold(metric, threshold) {
3453
+ if (threshold.alert_type === "CONFIDENCE_DROP") {
3454
+ return metric.current_value < threshold.absolute_threshold || metric.baseline_value > 0 && metric.current_value < metric.baseline_value * threshold.surge_multiplier;
3455
+ }
3456
+ if (threshold.alert_type === "APPROVAL_QUEUE_BACKLOG") {
3457
+ return metric.current_value > threshold.absolute_threshold;
3458
+ }
3459
+ const surgeTriggered = metric.baseline_value > 0 && metric.current_value > metric.baseline_value * threshold.surge_multiplier;
3460
+ const absoluteTriggered = metric.current_value > threshold.absolute_threshold;
3461
+ return surgeTriggered || absoluteTriggered;
3462
+ }
3463
+ // ---- 自动恢复 ----
3464
+ checkAutoRecover() {
3465
+ if (this.systemState.degrade.active && this.systemState.degrade.auto_recover_at) {
3466
+ if (Date.now() >= this.systemState.degrade.auto_recover_at) {
3467
+ this.systemState.degrade = {
3468
+ active: false,
3469
+ level: "LIGHT",
3470
+ reason: "Auto-recovered after cooldown",
3471
+ activated_at: null,
3472
+ auto_recover_at: null
3473
+ };
3474
+ }
3475
+ }
3476
+ }
3477
+ // ---- 手动操作 ----
3478
+ acknowledgeAlert(alertId, acknowledgedBy) {
3479
+ const alert = this.alertHistory.find((a) => a.alert_id === alertId);
3480
+ if (!alert) return false;
3481
+ alert.acknowledged = true;
3482
+ alert.acknowledged_by = acknowledgedBy;
3483
+ alert.acknowledged_at = Date.now();
3484
+ return true;
3485
+ }
3486
+ disableKillSwitch(reason, actor) {
3487
+ if (!this.systemState.kill_switch.enabled) return false;
3488
+ this.systemState.kill_switch = {
3489
+ enabled: false,
3490
+ reason: `Disabled by ${actor}: ${reason}`,
3491
+ enabled_at: null,
3492
+ enabled_by: actor,
3493
+ auto_triggered: false
3494
+ };
3495
+ return true;
3496
+ }
3497
+ resetDegrade() {
3498
+ this.systemState.degrade = {
3499
+ active: false,
3500
+ level: "LIGHT",
3501
+ reason: "Manual reset",
3502
+ activated_at: null,
3503
+ auto_recover_at: null
3504
+ };
3505
+ this.systemState.tightened_threshold_multiplier = 1;
3506
+ this.systemState.force_human_gate = false;
3507
+ }
3508
+ // ---- 查询 ----
3509
+ getSystemState() {
3510
+ return { ...this.systemState };
3511
+ }
3512
+ getAlertHistory(limit = 50) {
3513
+ return this.alertHistory.slice(-limit);
3514
+ }
3515
+ getActiveAlerts() {
3516
+ return this.alertHistory.filter((a) => !a.acknowledged);
3517
+ }
3518
+ getMetricsBuffer() {
3519
+ return [...this.metricsBuffer];
3520
+ }
3521
+ // ---- 辅助 ----
3522
+ formatAlertMessage(threshold, metric, surgeRatio) {
3523
+ return `[${threshold.severity}] ${threshold.alert_type}: ${metric.metric_name} = ${metric.current_value.toFixed(3)} (baseline: ${metric.baseline_value.toFixed(3)}, surge: ${surgeRatio.toFixed(1)}x, threshold: ${threshold.absolute_threshold})`;
3524
+ }
3525
+ };
3526
+
3527
+ // src/selfConstraintEngine.ts
3528
+ var DEFAULT_THRESHOLDS3 = {
3529
+ risk_density: 0.75,
3530
+ conflict_rate: 0.6,
3531
+ confidence_drop: 0.2,
3532
+ error_rate: 0.15,
3533
+ latency_p99_ms: 5e3,
3534
+ consecutive_failures: 5
3535
+ };
3536
+ var NORMAL_FLAGS = {
3537
+ enable_advanced_features: true,
3538
+ enable_auto_approve: true,
3539
+ enable_batch_operations: true,
3540
+ enable_external_api_calls: true,
3541
+ enable_write_operations: true,
3542
+ require_human_gate: false,
3543
+ require_dual_review: false,
3544
+ max_concurrent_decisions: 100,
3545
+ decision_delay_ms: 0
3546
+ };
3547
+ var CAUTIOUS_FLAGS = {
3548
+ enable_advanced_features: true,
3549
+ enable_auto_approve: false,
3550
+ // 关闭自动审批
3551
+ enable_batch_operations: true,
3552
+ enable_external_api_calls: true,
3553
+ enable_write_operations: true,
3554
+ require_human_gate: false,
3555
+ require_dual_review: false,
3556
+ max_concurrent_decisions: 50,
3557
+ decision_delay_ms: 500
3558
+ // 500ms 延迟
3559
+ };
3560
+ var RESTRICTED_FLAGS = {
3561
+ enable_advanced_features: false,
3562
+ // 关闭高级功能
3563
+ enable_auto_approve: false,
3564
+ enable_batch_operations: false,
3565
+ // 关闭批量操作
3566
+ enable_external_api_calls: true,
3567
+ enable_write_operations: true,
3568
+ require_human_gate: true,
3569
+ // 强制人工门禁
3570
+ require_dual_review: false,
3571
+ max_concurrent_decisions: 10,
3572
+ decision_delay_ms: 2e3
3573
+ // 2s 延迟
3574
+ };
3575
+ var LOCKDOWN_FLAGS = {
3576
+ enable_advanced_features: false,
3577
+ enable_auto_approve: false,
3578
+ enable_batch_operations: false,
3579
+ enable_external_api_calls: false,
3580
+ // 关闭外部调用
3581
+ enable_write_operations: false,
3582
+ // 关闭写操作
3583
+ require_human_gate: true,
3584
+ require_dual_review: true,
3585
+ // 双人审核
3586
+ max_concurrent_decisions: 1,
3587
+ decision_delay_ms: 5e3
3588
+ // 5s 延迟
3589
+ };
3590
+ var LEVEL_FLAGS_MAP = {
3591
+ NORMAL: NORMAL_FLAGS,
3592
+ CAUTIOUS: CAUTIOUS_FLAGS,
3593
+ RESTRICTED: RESTRICTED_FLAGS,
3594
+ LOCKDOWN: LOCKDOWN_FLAGS
3595
+ };
3596
+ var SelfConstraintEngine = class {
3597
+ config;
3598
+ state;
3599
+ constructor(config) {
3600
+ this.config = {
3601
+ thresholds: config?.thresholds || DEFAULT_THRESHOLDS3,
3602
+ flags: config?.flags || NORMAL_FLAGS,
3603
+ auto_recover_after_minutes: config?.auto_recover_after_minutes || 30,
3604
+ evaluation_interval_seconds: config?.evaluation_interval_seconds || 60
3605
+ };
3606
+ this.state = {
3607
+ current_level: "NORMAL",
3608
+ active_modes: [],
3609
+ flags: { ...NORMAL_FLAGS },
3610
+ activated_at: null,
3611
+ auto_recover_at: null,
3612
+ last_evaluation_at: 0,
3613
+ evaluation_count: 0,
3614
+ constraint_history: []
3615
+ };
3616
+ }
3617
+ // ---- 核心: 评估自我约束 ----
3618
+ evaluate(metrics) {
3619
+ const triggers = [];
3620
+ const modes = /* @__PURE__ */ new Set();
3621
+ triggers.push({
3622
+ metric_name: "risk_density",
3623
+ current_value: metrics.risk_density,
3624
+ threshold_value: this.config.thresholds.risk_density,
3625
+ exceeded: metrics.risk_density >= this.config.thresholds.risk_density
3626
+ });
3627
+ if (metrics.risk_density >= this.config.thresholds.risk_density) {
3628
+ modes.add("CAPABILITY_DOWN");
3629
+ modes.add("PERMISSION_DOWN");
3630
+ }
3631
+ triggers.push({
3632
+ metric_name: "conflict_rate",
3633
+ current_value: metrics.conflict_rate,
3634
+ threshold_value: this.config.thresholds.conflict_rate,
3635
+ exceeded: metrics.conflict_rate >= this.config.thresholds.conflict_rate
3636
+ });
3637
+ if (metrics.conflict_rate >= this.config.thresholds.conflict_rate) {
3638
+ modes.add("SPEED_DOWN");
3639
+ modes.add("PERMISSION_DOWN");
3640
+ }
3641
+ const confidenceDrop = metrics.prev_avg_confidence > 0 ? (metrics.prev_avg_confidence - metrics.avg_confidence) / metrics.prev_avg_confidence : 0;
3642
+ triggers.push({
3643
+ metric_name: "confidence_drop",
3644
+ current_value: confidenceDrop,
3645
+ threshold_value: this.config.thresholds.confidence_drop,
3646
+ exceeded: confidenceDrop >= this.config.thresholds.confidence_drop
3647
+ });
3648
+ if (confidenceDrop >= this.config.thresholds.confidence_drop) {
3649
+ modes.add("SPEED_DOWN");
3650
+ }
3651
+ triggers.push({
3652
+ metric_name: "error_rate",
3653
+ current_value: metrics.error_rate,
3654
+ threshold_value: this.config.thresholds.error_rate,
3655
+ exceeded: metrics.error_rate >= this.config.thresholds.error_rate
3656
+ });
3657
+ if (metrics.error_rate >= this.config.thresholds.error_rate) {
3658
+ modes.add("CAPABILITY_DOWN");
3659
+ }
3660
+ triggers.push({
3661
+ metric_name: "latency_p99_ms",
3662
+ current_value: metrics.latency_p99_ms,
3663
+ threshold_value: this.config.thresholds.latency_p99_ms,
3664
+ exceeded: metrics.latency_p99_ms >= this.config.thresholds.latency_p99_ms
3665
+ });
3666
+ if (metrics.latency_p99_ms >= this.config.thresholds.latency_p99_ms) {
3667
+ modes.add("SPEED_DOWN");
3668
+ }
3669
+ triggers.push({
3670
+ metric_name: "consecutive_failures",
3671
+ current_value: metrics.consecutive_failures,
3672
+ threshold_value: this.config.thresholds.consecutive_failures,
3673
+ exceeded: metrics.consecutive_failures >= this.config.thresholds.consecutive_failures
3674
+ });
3675
+ if (metrics.consecutive_failures >= this.config.thresholds.consecutive_failures) {
3676
+ modes.add("CAPABILITY_DOWN");
3677
+ modes.add("PERMISSION_DOWN");
3678
+ }
3679
+ const triggeredCount = triggers.filter((t) => t.exceeded).length;
3680
+ const level = this.calculateLevel(triggeredCount, metrics.system_pressure);
3681
+ const activeModes = Array.from(modes);
3682
+ const flagsApplied = LEVEL_FLAGS_MAP[level];
3683
+ this.applyConstraint(level, activeModes, flagsApplied);
3684
+ const decision = {
3685
+ decision_id: `sc_${Date.now()}_${this.state.evaluation_count}`,
3686
+ timestamp: Date.now(),
3687
+ level,
3688
+ modes_activated: activeModes,
3689
+ triggers,
3690
+ flags_applied: flagsApplied,
3691
+ reason_code: activeModes.length > 0 ? "SELF_CONSTRAINT_ACTIVATED" : "NORMAL",
3692
+ auto_recover_at: level !== "NORMAL" ? Date.now() + this.config.auto_recover_after_minutes * 60 * 1e3 : null
3693
+ };
3694
+ this.state.constraint_history.push(decision);
3695
+ if (this.state.constraint_history.length > 100) {
3696
+ this.state.constraint_history = this.state.constraint_history.slice(-100);
3697
+ }
3698
+ this.state.evaluation_count++;
3699
+ this.state.last_evaluation_at = Date.now();
3700
+ return decision;
3701
+ }
3702
+ // ---- 约束级别计算 ----
3703
+ calculateLevel(triggeredCount, systemPressure) {
3704
+ const score = triggeredCount + systemPressure * 3;
3705
+ if (score >= 5) return "LOCKDOWN";
3706
+ if (score >= 3) return "RESTRICTED";
3707
+ if (score >= 1) return "CAUTIOUS";
3708
+ return "NORMAL";
3709
+ }
3710
+ // ---- 应用约束 ----
3711
+ applyConstraint(level, modes, flags) {
3712
+ const wasNormal = this.state.current_level === "NORMAL";
3713
+ this.state.current_level = level;
3714
+ this.state.active_modes = modes;
3715
+ this.state.flags = { ...flags };
3716
+ if (level !== "NORMAL" && wasNormal) {
3717
+ this.state.activated_at = Date.now();
3718
+ this.state.auto_recover_at = Date.now() + this.config.auto_recover_after_minutes * 60 * 1e3;
3719
+ } else if (level === "NORMAL") {
3720
+ this.state.activated_at = null;
3721
+ this.state.auto_recover_at = null;
3722
+ }
3723
+ }
3724
+ // ---- 自动恢复检查 ----
3725
+ checkAutoRecover() {
3726
+ if (this.state.current_level === "NORMAL") return false;
3727
+ if (!this.state.auto_recover_at) return false;
3728
+ if (Date.now() >= this.state.auto_recover_at) {
3729
+ this.reset();
3730
+ return true;
3731
+ }
3732
+ return false;
3733
+ }
3734
+ // ---- 手动操作 ----
3735
+ reset() {
3736
+ this.state.current_level = "NORMAL";
3737
+ this.state.active_modes = [];
3738
+ this.state.flags = { ...NORMAL_FLAGS };
3739
+ this.state.activated_at = null;
3740
+ this.state.auto_recover_at = null;
3741
+ }
3742
+ forceLevel(level) {
3743
+ const flags = LEVEL_FLAGS_MAP[level];
3744
+ this.applyConstraint(level, level === "NORMAL" ? [] : ["CAPABILITY_DOWN", "PERMISSION_DOWN"], flags);
3745
+ }
3746
+ // ---- 决策前检查 (Gate 集成) ----
3747
+ preDecisionCheck(action, resource) {
3748
+ const flags = this.state.flags;
3749
+ if (!flags.enable_write_operations && this.isWriteAction(action)) {
3750
+ return {
3751
+ allowed: false,
3752
+ delay_ms: 0,
3753
+ requires_human: true,
3754
+ requires_dual_review: flags.require_dual_review,
3755
+ reason: `Write operations disabled at ${this.state.current_level} level`
3756
+ };
3757
+ }
3758
+ if (!flags.enable_external_api_calls && this.isExternalAction(action)) {
3759
+ return {
3760
+ allowed: false,
3761
+ delay_ms: 0,
3762
+ requires_human: true,
3763
+ requires_dual_review: flags.require_dual_review,
3764
+ reason: `External API calls disabled at ${this.state.current_level} level`
3765
+ };
3766
+ }
3767
+ if (!flags.enable_batch_operations && this.isBatchAction(action)) {
3768
+ return {
3769
+ allowed: false,
3770
+ delay_ms: 0,
3771
+ requires_human: true,
3772
+ requires_dual_review: false,
3773
+ reason: `Batch operations disabled at ${this.state.current_level} level`
3774
+ };
3775
+ }
3776
+ return {
3777
+ allowed: true,
3778
+ delay_ms: flags.decision_delay_ms,
3779
+ requires_human: flags.require_human_gate,
3780
+ requires_dual_review: flags.require_dual_review,
3781
+ reason: this.state.current_level === "NORMAL" ? "OK" : `Constrained at ${this.state.current_level} level`
3782
+ };
3783
+ }
3784
+ // ---- 查询 ----
3785
+ getState() {
3786
+ return {
3787
+ ...this.state,
3788
+ flags: { ...this.state.flags },
3789
+ active_modes: [...this.state.active_modes],
3790
+ constraint_history: [...this.state.constraint_history]
3791
+ };
3792
+ }
3793
+ getCurrentLevel() {
3794
+ return this.state.current_level;
3795
+ }
3796
+ getFlags() {
3797
+ return { ...this.state.flags };
3798
+ }
3799
+ isConstrained() {
3800
+ return this.state.current_level !== "NORMAL";
3801
+ }
3802
+ // ---- 辅助 ----
3803
+ isWriteAction(action) {
3804
+ const writePatterns = ["write", "create", "update", "delete", "insert", "modify", "patch", "put"];
3805
+ return writePatterns.some((p) => action.toLowerCase().includes(p));
3806
+ }
3807
+ isExternalAction(action) {
3808
+ const externalPatterns = ["external", "api_call", "webhook", "http", "fetch", "request"];
3809
+ return externalPatterns.some((p) => action.toLowerCase().includes(p));
3810
+ }
3811
+ isBatchAction(action) {
3812
+ const batchPatterns = ["batch", "bulk", "mass", "multi"];
3813
+ return batchPatterns.some((p) => action.toLowerCase().includes(p));
3814
+ }
3815
+ };
3816
+
3817
+ // src/contributionSettlement.ts
3818
+ var DEFAULT_SCORE_CONFIG = {
3819
+ version: "1.0.0",
3820
+ weight_risk: 0.35,
3821
+ weight_cost: 0.25,
3822
+ weight_human: 0.2,
3823
+ weight_stability: 0.2,
3824
+ weight_penalty: 1,
3825
+ caps: {
3826
+ max_single_event: 100,
3827
+ max_risk_positive_when_risk_up: false
3828
+ },
3829
+ guardrails: [
3830
+ "RISK_UP_BLOCKS_POSITIVE",
3831
+ "EVIDENCE_DOWNGRADE_NEGATIVE",
3832
+ "OVERRIDE_INCREASE_PENALTY"
3833
+ ],
3834
+ approved_by: "system",
3835
+ approved_at: Date.now()
3836
+ };
3837
+ var MVP_ATTRIBUTION_RULES = [
3838
+ {
3839
+ condition: "RULE_TRIGGERED_BLOCK_WARN",
3840
+ target_entity_type: "rule",
3841
+ target_entity_field: "rule_id",
3842
+ weight: 1
3843
+ },
3844
+ {
3845
+ condition: "EVIDENCE_UPGRADED_ALLOW",
3846
+ target_entity_type: "tool",
3847
+ target_entity_field: "evidence_source",
3848
+ weight: 0.8
3849
+ },
3850
+ {
3851
+ condition: "MODEL_ROUTE_CHEAPER_SAME_RESULT",
3852
+ target_entity_type: "model",
3853
+ target_entity_field: "modelops_route_id",
3854
+ weight: 0.7
3855
+ },
3856
+ {
3857
+ condition: "CACHE_HIT_SKIP_TOOL",
3858
+ target_entity_type: "system",
3859
+ target_entity_field: "context_accelerator",
3860
+ weight: 0.6
3861
+ },
3862
+ {
3863
+ condition: "HUMAN_OVERRIDE_CORRECTION",
3864
+ target_entity_type: "human",
3865
+ target_entity_field: "actor_id",
3866
+ weight: 0.5
3867
+ }
3868
+ ];
3869
+ var BUILTIN_PENALTY_CHECKS = [
3870
+ {
3871
+ name: "OVERRIDE_INCREASE",
3872
+ detect: (_events, ctx) => {
3873
+ if (ctx.override_count_delta > 0) {
3874
+ return ctx.override_count_delta * 5;
3875
+ }
3876
+ return 0;
3877
+ }
3878
+ },
3879
+ {
3880
+ name: "REPLAY_FAIL_INCREASE",
3881
+ detect: (_events, ctx) => {
3882
+ if (ctx.replay_fail_delta > 0) {
3883
+ return ctx.replay_fail_delta * 10;
3884
+ }
3885
+ return 0;
3886
+ }
3887
+ },
3888
+ {
3889
+ name: "RISK_REGRESSION",
3890
+ detect: (_events, ctx) => {
3891
+ if (ctx.risk_regression) {
3892
+ return 50;
3893
+ }
3894
+ return 0;
3895
+ }
3896
+ },
3897
+ {
3898
+ name: "EVIDENCE_DOWNGRADE",
3899
+ detect: (_events, ctx) => {
3900
+ if (ctx.evidence_downgrade) {
3901
+ return 30;
3902
+ }
3903
+ return 0;
3904
+ }
3905
+ },
3906
+ {
3907
+ name: "SELF_MANUFACTURE_DETECT",
3908
+ detect: (events, _ctx) => {
3909
+ const entityMap = /* @__PURE__ */ new Map();
3910
+ for (const e of events) {
3911
+ const key = `${e.entity_type}:${e.entity_id}`;
3912
+ const entry = entityMap.get(key) || { negative: 0, positive: 0 };
3913
+ if (e.delta_value < 0) entry.negative += Math.abs(e.delta_value);
3914
+ else entry.positive += e.delta_value;
3915
+ entityMap.set(key, entry);
3916
+ }
3917
+ let penalty = 0;
3918
+ for (const [, entry] of entityMap) {
3919
+ if (entry.negative > 20 && entry.positive > 20) {
3920
+ const ratio = Math.min(entry.negative, entry.positive) / Math.max(entry.negative, entry.positive);
3921
+ if (ratio > 0.7) {
3922
+ penalty += 25;
3923
+ }
3924
+ }
3925
+ }
3926
+ return penalty;
3927
+ }
3928
+ }
3929
+ ];
3930
+ var ContributionSettlementEngine = class {
3931
+ config;
3932
+ attributionRules;
3933
+ penaltyChecks;
3934
+ eventStore = [];
3935
+ scoreStore = [];
3936
+ constructor(config, customRules, customPenalties) {
3937
+ this.config = { ...DEFAULT_SCORE_CONFIG, ...config };
3938
+ this.attributionRules = customRules || MVP_ATTRIBUTION_RULES;
3939
+ this.penaltyChecks = [...BUILTIN_PENALTY_CHECKS, ...customPenalties || []];
3940
+ }
3941
+ // ---- 事件记录 ----
3942
+ recordEvent(event) {
3943
+ if (Math.abs(event.delta_value) > this.config.caps.max_single_event) {
3944
+ event.delta_value = event.delta_value > 0 ? this.config.caps.max_single_event : -this.config.caps.max_single_event;
3945
+ }
3946
+ const exists = this.eventStore.find((e) => e.event_id === event.event_id);
3947
+ if (exists) return exists;
3948
+ this.eventStore.push(event);
3949
+ return event;
3950
+ }
3951
+ // ---- 归因 ----
3952
+ attribute(traceId, condition, entityType, entityId) {
3953
+ const rule = this.attributionRules.find((r) => r.condition === condition);
3954
+ if (!rule) return null;
3955
+ const event = {
3956
+ event_id: `attr_${traceId}_${Date.now()}`,
3957
+ trace_id: traceId,
3958
+ decision_id: traceId,
3959
+ tenant_id: "default",
3960
+ entity_type: entityType,
3961
+ entity_id: entityId,
3962
+ dimension: this.inferDimension(condition),
3963
+ delta_value: rule.weight * 10,
3964
+ // 基础分 * 权重
3965
+ delta_confidence: rule.weight,
3966
+ baseline_ref: "current",
3967
+ evidence_bundle_hash: "",
3968
+ created_at: Date.now()
3969
+ };
3970
+ return this.recordEvent(event);
3971
+ }
3972
+ // ---- 窗口结算 ----
3973
+ settle(context) {
3974
+ const windowEvents = this.eventStore.filter(
3975
+ (e) => e.tenant_id === context.tenant_id && e.created_at >= context.window_start && e.created_at <= context.window_end
3976
+ );
3977
+ const entityGroups = /* @__PURE__ */ new Map();
3978
+ for (const e of windowEvents) {
3979
+ const key = `${e.entity_type}:${e.entity_id}`;
3980
+ const group = entityGroups.get(key) || [];
3981
+ group.push(e);
3982
+ entityGroups.set(key, group);
3983
+ }
3984
+ const scores = [];
3985
+ for (const [key, events] of entityGroups) {
3986
+ const [entityType, entityId] = key.split(":");
3987
+ let scoreRisk = 0, scoreCost = 0, scoreHuman = 0, scoreStability = 0;
3988
+ let totalConfidence = 0;
3989
+ for (const e of events) {
3990
+ const val = e.delta_value * e.delta_confidence;
3991
+ switch (e.dimension) {
3992
+ case "RISK":
3993
+ scoreRisk += val;
3994
+ break;
3995
+ case "COST":
3996
+ scoreCost += val;
3997
+ break;
3998
+ case "HUMAN":
3999
+ scoreHuman += val;
4000
+ break;
4001
+ case "STABILITY":
4002
+ scoreStability += val;
4003
+ break;
4004
+ }
4005
+ totalConfidence += e.delta_confidence;
4006
+ }
4007
+ if (!this.config.caps.max_risk_positive_when_risk_up && context.risk_regression) {
4008
+ scoreRisk = Math.min(scoreRisk, 0);
4009
+ scoreCost = Math.min(scoreCost, 0);
4010
+ scoreHuman = Math.min(scoreHuman, 0);
4011
+ scoreStability = Math.min(scoreStability, 0);
4012
+ }
4013
+ let penaltyTotal = 0;
4014
+ for (const check of this.penaltyChecks) {
4015
+ penaltyTotal += check.detect(events, context);
4016
+ }
4017
+ const scoreTotal = this.config.weight_risk * scoreRisk + this.config.weight_cost * scoreCost + this.config.weight_human * scoreHuman + this.config.weight_stability * scoreStability - this.config.weight_penalty * penaltyTotal;
4018
+ const avgConfidence = events.length > 0 ? totalConfidence / events.length : 0;
4019
+ const score = {
4020
+ score_id: `score_${entityType}_${entityId}_${context.window_start}`,
4021
+ window_start: context.window_start,
4022
+ window_end: context.window_end,
4023
+ tenant_id: context.tenant_id,
4024
+ entity_type: entityType,
4025
+ entity_id: entityId,
4026
+ score_risk: Math.round(scoreRisk * 100) / 100,
4027
+ score_cost: Math.round(scoreCost * 100) / 100,
4028
+ score_human: Math.round(scoreHuman * 100) / 100,
4029
+ score_stability: Math.round(scoreStability * 100) / 100,
4030
+ score_total: Math.round(scoreTotal * 100) / 100,
4031
+ penalty_total: Math.round(penaltyTotal * 100) / 100,
4032
+ confidence: Math.round(avgConfidence * 100) / 100,
4033
+ score_config_version: this.config.version,
4034
+ created_at: Date.now()
4035
+ };
4036
+ scores.push(score);
4037
+ this.scoreStore.push(score);
4038
+ }
4039
+ return scores;
4040
+ }
4041
+ // ---- 控制面联动 ----
4042
+ getResourceAllocation(entityType, entityId) {
4043
+ const recentScores = this.scoreStore.filter(
4044
+ (s) => s.entity_type === entityType && s.entity_id === entityId
4045
+ );
4046
+ if (recentScores.length === 0) {
4047
+ return {
4048
+ token_budget_multiplier: 1,
4049
+ concurrency_quota_multiplier: 1,
4050
+ auto_approve_eligible: false,
4051
+ requires_dual_review: false
4052
+ };
4053
+ }
4054
+ const latestScore = recentScores[recentScores.length - 1];
4055
+ const total = latestScore.score_total;
4056
+ return {
4057
+ token_budget_multiplier: total > 50 ? 1.5 : total > 0 ? 1 : 0.5,
4058
+ concurrency_quota_multiplier: total > 50 ? 1.3 : total > 0 ? 1 : 0.7,
4059
+ auto_approve_eligible: total > 80 && latestScore.penalty_total === 0,
4060
+ requires_dual_review: total < -20 || latestScore.penalty_total > 30
4061
+ };
4062
+ }
4063
+ // ---- 审计抽查 ----
4064
+ auditSample(entityType, entityId, sampleSize = 3) {
4065
+ const entityEvents = this.eventStore.filter(
4066
+ (e) => e.entity_type === entityType && e.entity_id === entityId
4067
+ );
4068
+ const shuffled = [...entityEvents].sort(() => Math.random() - 0.5);
4069
+ return shuffled.slice(0, Math.min(sampleSize, shuffled.length));
4070
+ }
4071
+ // ---- 辅助 ----
4072
+ inferDimension(condition) {
4073
+ if (condition.includes("RULE") || condition.includes("BLOCK")) return "RISK";
4074
+ if (condition.includes("COST") || condition.includes("CACHE") || condition.includes("CHEAPER")) return "COST";
4075
+ if (condition.includes("HUMAN") || condition.includes("OVERRIDE")) return "HUMAN";
4076
+ return "STABILITY";
4077
+ }
4078
+ getConfig() {
4079
+ return { ...this.config };
4080
+ }
4081
+ getEventCount() {
4082
+ return this.eventStore.length;
4083
+ }
4084
+ getScoreCount() {
4085
+ return this.scoreStore.length;
4086
+ }
4087
+ };
4088
+
4089
+ // src/overrideDriftAnalyzer.ts
4090
+ var DEFAULT_CONFIG6 = {
4091
+ baseline_window_hours: 168,
4092
+ // 7 天基线
4093
+ analysis_window_hours: 24,
4094
+ // 24 小时分析窗口
4095
+ rate_drift_threshold: 0.3,
4096
+ // override 率偏离 30%
4097
+ concentration_threshold: 0.5,
4098
+ // 单一实体占比超 50%
4099
+ risk_drift_threshold: 0.4,
4100
+ // 高风险 override 占比偏离 40%
4101
+ temporal_drift_threshold: 0.3,
4102
+ // 时间分布偏离 30%
4103
+ composite_alert_threshold: 0.5,
4104
+ // 综合漂移指数超 0.5 告警
4105
+ min_sample_size: 10
4106
+ // 最小样本量
4107
+ };
4108
+ var OverrideDriftAnalyzer = class {
4109
+ config;
4110
+ events = [];
4111
+ baselineWindow = null;
4112
+ alerts = [];
4113
+ constructor(config) {
4114
+ this.config = { ...DEFAULT_CONFIG6, ...config };
4115
+ }
4116
+ // ---- 事件记录 ----
4117
+ recordOverride(event) {
4118
+ if (this.events.find((e) => e.event_id === event.event_id)) return;
4119
+ this.events.push(event);
4120
+ }
4121
+ // ---- 窗口统计 ----
4122
+ computeWindow(start, end, totalDecisions) {
4123
+ const windowEvents = this.events.filter(
4124
+ (e) => e.created_at >= start && e.created_at <= end
4125
+ );
4126
+ const byActor = /* @__PURE__ */ new Map();
4127
+ const byRule = /* @__PURE__ */ new Map();
4128
+ const byRiskLevel = { LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0 };
4129
+ const byHour = new Array(24).fill(0);
4130
+ for (const e of windowEvents) {
4131
+ byActor.set(e.actor_id, (byActor.get(e.actor_id) || 0) + 1);
4132
+ byRule.set(e.rule_id, (byRule.get(e.rule_id) || 0) + 1);
4133
+ byRiskLevel[e.risk_level] = (byRiskLevel[e.risk_level] || 0) + 1;
4134
+ const hour = new Date(e.created_at).getHours();
4135
+ byHour[hour]++;
4136
+ }
4137
+ const total = totalDecisions || Math.max(windowEvents.length * 5, 1);
4138
+ return {
4139
+ window_start: start,
4140
+ window_end: end,
4141
+ total_decisions: total,
4142
+ total_overrides: windowEvents.length,
4143
+ override_rate: total > 0 ? windowEvents.length / total : 0,
4144
+ by_actor: byActor,
4145
+ by_rule: byRule,
4146
+ by_risk_level: byRiskLevel,
4147
+ by_hour: byHour
4148
+ };
4149
+ }
4150
+ // ---- 基线计算 ----
4151
+ updateBaseline(totalDecisions) {
4152
+ const now = Date.now();
4153
+ const start = now - this.config.baseline_window_hours * 60 * 60 * 1e3;
4154
+ this.baselineWindow = this.computeWindow(start, now, totalDecisions);
4155
+ return this.baselineWindow;
4156
+ }
4157
+ // ---- 漂移指数计算 ----
4158
+ calculateDriftIndex(currentWindow, totalDecisions) {
4159
+ const now = Date.now();
4160
+ const current = currentWindow || this.computeWindow(
4161
+ now - this.config.analysis_window_hours * 60 * 60 * 1e3,
4162
+ now,
4163
+ totalDecisions
4164
+ );
4165
+ if (!this.baselineWindow) {
4166
+ this.updateBaseline(totalDecisions);
4167
+ }
4168
+ const baseline = this.baselineWindow;
4169
+ const rateDrift = baseline.override_rate > 0 ? Math.abs(current.override_rate - baseline.override_rate) / baseline.override_rate : current.override_rate > 0 ? 1 : 0;
4170
+ const actorConcentration = this.calculateConcentration(current.by_actor, current.total_overrides);
4171
+ const baselineActorConc = this.calculateConcentration(baseline.by_actor, baseline.total_overrides);
4172
+ const concentrationDrift = Math.abs(actorConcentration - baselineActorConc);
4173
+ const currentHighRisk = ((current.by_risk_level["HIGH"] || 0) + (current.by_risk_level["CRITICAL"] || 0)) / Math.max(current.total_overrides, 1);
4174
+ const baselineHighRisk = ((baseline.by_risk_level["HIGH"] || 0) + (baseline.by_risk_level["CRITICAL"] || 0)) / Math.max(baseline.total_overrides, 1);
4175
+ const riskDrift = Math.abs(currentHighRisk - baselineHighRisk);
4176
+ const temporalDrift = this.calculateTemporalDrift(current.by_hour, baseline.by_hour);
4177
+ const composite = rateDrift * 0.35 + concentrationDrift * 0.25 + riskDrift * 0.25 + temporalDrift * 0.15;
4178
+ const trend = this.determineTrend(composite);
4179
+ return {
4180
+ value: Math.min(Math.round(composite * 1e3) / 1e3, 1),
4181
+ rate_drift: Math.round(rateDrift * 1e3) / 1e3,
4182
+ concentration_drift: Math.round(concentrationDrift * 1e3) / 1e3,
4183
+ risk_drift: Math.round(riskDrift * 1e3) / 1e3,
4184
+ temporal_drift: Math.round(temporalDrift * 1e3) / 1e3,
4185
+ trend
4186
+ };
4187
+ }
4188
+ // ---- 分析 & 告警 ----
4189
+ analyze(totalDecisions) {
4190
+ const driftIndex = this.calculateDriftIndex(void 0, totalDecisions);
4191
+ if (driftIndex.value < this.config.composite_alert_threshold) {
4192
+ return null;
4193
+ }
4194
+ const patterns = this.detectPatterns(driftIndex);
4195
+ const recommendations = this.generateRecommendations(driftIndex, patterns);
4196
+ const severity = driftIndex.value >= 0.8 ? "CRITICAL" : driftIndex.value >= 0.5 ? "WARN" : "INFO";
4197
+ const alert = {
4198
+ alert_id: `da_${Date.now()}`,
4199
+ drift_index: driftIndex,
4200
+ severity,
4201
+ message: `Override drift detected: composite index = ${driftIndex.value} (${driftIndex.trend})`,
4202
+ patterns_detected: patterns,
4203
+ recommendations,
4204
+ created_at: Date.now()
4205
+ };
4206
+ this.alerts.push(alert);
4207
+ return alert;
4208
+ }
4209
+ // ---- 模式检测 ----
4210
+ detectPatterns(driftIndex) {
4211
+ const patterns = [];
4212
+ if (driftIndex.rate_drift > this.config.rate_drift_threshold) {
4213
+ patterns.push({
4214
+ pattern_type: "RATE_SPIKE",
4215
+ description: `Override rate increased by ${(driftIndex.rate_drift * 100).toFixed(1)}% from baseline`,
4216
+ evidence: { rate_drift: driftIndex.rate_drift },
4217
+ confidence: Math.min(driftIndex.rate_drift, 1)
4218
+ });
4219
+ }
4220
+ if (driftIndex.concentration_drift > this.config.concentration_threshold) {
4221
+ patterns.push({
4222
+ pattern_type: "ACTOR_CONCENTRATION",
4223
+ description: "Override activity concentrated on fewer actors than baseline",
4224
+ evidence: { concentration_drift: driftIndex.concentration_drift },
4225
+ confidence: Math.min(driftIndex.concentration_drift, 1)
4226
+ });
4227
+ }
4228
+ if (driftIndex.risk_drift > this.config.risk_drift_threshold) {
4229
+ patterns.push({
4230
+ pattern_type: "RISK_ESCALATION",
4231
+ description: `High-risk override proportion shifted by ${(driftIndex.risk_drift * 100).toFixed(1)}%`,
4232
+ evidence: { risk_drift: driftIndex.risk_drift },
4233
+ confidence: Math.min(driftIndex.risk_drift, 1)
4234
+ });
4235
+ }
4236
+ if (driftIndex.temporal_drift > this.config.temporal_drift_threshold) {
4237
+ patterns.push({
4238
+ pattern_type: "TIME_ANOMALY",
4239
+ description: "Override time distribution deviates from baseline pattern",
4240
+ evidence: { temporal_drift: driftIndex.temporal_drift },
4241
+ confidence: Math.min(driftIndex.temporal_drift, 1)
4242
+ });
4243
+ }
4244
+ return patterns;
4245
+ }
4246
+ // ---- 建议生成 ----
4247
+ generateRecommendations(driftIndex, patterns) {
4248
+ const recs = [];
4249
+ if (patterns.some((p) => p.pattern_type === "RATE_SPIKE")) {
4250
+ recs.push("Review recent policy changes that may have increased false positives");
4251
+ recs.push("Check if new rules are overly restrictive, causing excessive overrides");
4252
+ }
4253
+ if (patterns.some((p) => p.pattern_type === "ACTOR_CONCENTRATION")) {
4254
+ recs.push("Investigate concentrated override activity for potential abuse");
4255
+ recs.push("Consider implementing per-actor override quotas");
4256
+ }
4257
+ if (patterns.some((p) => p.pattern_type === "RISK_ESCALATION")) {
4258
+ recs.push("Audit high-risk overrides for potential security implications");
4259
+ recs.push("Consider requiring dual approval for high-risk overrides");
4260
+ }
4261
+ if (patterns.some((p) => p.pattern_type === "TIME_ANOMALY")) {
4262
+ recs.push("Check for automated override scripts running at unusual hours");
4263
+ recs.push("Review access patterns during off-hours");
4264
+ }
4265
+ if (driftIndex.value >= 0.8) {
4266
+ recs.push("CRITICAL: Consider activating self-constraint engine to restrict override capability");
4267
+ }
4268
+ return recs;
4269
+ }
4270
+ // ---- 辅助计算 ----
4271
+ calculateConcentration(distribution, total) {
4272
+ if (total === 0) return 0;
4273
+ let herfindahl = 0;
4274
+ for (const [, count] of distribution) {
4275
+ const share = count / total;
4276
+ herfindahl += share * share;
4277
+ }
4278
+ return herfindahl;
4279
+ }
4280
+ calculateTemporalDrift(current, baseline) {
4281
+ const currentTotal = current.reduce((a, b) => a + b, 0) || 1;
4282
+ const baselineTotal = baseline.reduce((a, b) => a + b, 0) || 1;
4283
+ let divergence = 0;
4284
+ for (let i = 0; i < 24; i++) {
4285
+ const p = current[i] / currentTotal;
4286
+ const q = baseline[i] / baselineTotal || 1 / 24;
4287
+ if (p > 0) {
4288
+ divergence += p * Math.log(p / q);
4289
+ }
4290
+ }
4291
+ return Math.min(divergence / 2, 1);
4292
+ }
4293
+ determineTrend(composite) {
4294
+ const recentAlerts = this.alerts.slice(-5);
4295
+ if (recentAlerts.length < 2) return "STABLE";
4296
+ const values = recentAlerts.map((a) => a.drift_index.value);
4297
+ const diffs = values.slice(1).map((v, i) => v - values[i]);
4298
+ const avgDiff = diffs.reduce((a, b) => a + b, 0) / diffs.length;
4299
+ const variance = diffs.reduce((a, b) => a + (b - avgDiff) ** 2, 0) / diffs.length;
4300
+ if (variance > 0.1) return "VOLATILE";
4301
+ if (avgDiff > 0.05) return "RISING";
4302
+ if (avgDiff < -0.05) return "FALLING";
4303
+ return "STABLE";
4304
+ }
4305
+ // ---- 查询 ----
4306
+ getAlerts(limit = 20) {
4307
+ return this.alerts.slice(-limit);
4308
+ }
4309
+ getEventCount() {
4310
+ return this.events.length;
4311
+ }
4312
+ getLatestDriftIndex(totalDecisions) {
4313
+ return this.calculateDriftIndex(void 0, totalDecisions);
4314
+ }
4315
+ getStats() {
4316
+ const now = Date.now();
4317
+ const currentWindow = this.computeWindow(
4318
+ now - this.config.analysis_window_hours * 60 * 60 * 1e3,
4319
+ now
4320
+ );
4321
+ return {
4322
+ total_events: this.events.length,
4323
+ total_alerts: this.alerts.length,
4324
+ baseline_override_rate: this.baselineWindow?.override_rate || 0,
4325
+ current_override_rate: currentWindow.override_rate
4326
+ };
4327
+ }
4328
+ };
4329
+
4330
+ // src/cockpitDataService.ts
4331
+ var TIME_WINDOWS = {
4332
+ "1h": { label: "1 \u5C0F\u65F6", seconds: 3600 },
4333
+ "6h": { label: "6 \u5C0F\u65F6", seconds: 21600 },
4334
+ "24h": { label: "24 \u5C0F\u65F6", seconds: 86400 },
4335
+ "7d": { label: "7 \u5929", seconds: 604800 },
4336
+ "30d": { label: "30 \u5929", seconds: 2592e3 }
4337
+ };
4338
+ var collectors = [];
4339
+ function registerMetricCollector(collector) {
4340
+ const exists = collectors.findIndex((c) => c.name === collector.name);
4341
+ if (exists >= 0) {
4342
+ collectors[exists] = collector;
4343
+ } else {
4344
+ collectors.push(collector);
4345
+ }
4346
+ }
4347
+ registerMetricCollector({
4348
+ name: "gate_requests_total",
4349
+ category: "gate",
4350
+ unit: "req/min",
4351
+ collect: async () => 0
4352
+ });
4353
+ registerMetricCollector({
4354
+ name: "gate_block_rate",
4355
+ category: "gate",
4356
+ unit: "%",
4357
+ collect: async () => 0
4358
+ });
4359
+ registerMetricCollector({
4360
+ name: "audit_events_total",
4361
+ category: "audit",
4362
+ unit: "events/min",
4363
+ collect: async () => 0
4364
+ });
4365
+ registerMetricCollector({
4366
+ name: "trust_score",
4367
+ category: "trust",
4368
+ unit: "score",
4369
+ collect: async () => 85
4370
+ });
4371
+ registerMetricCollector({
4372
+ name: "budget_utilization",
4373
+ category: "budget",
4374
+ unit: "%",
4375
+ collect: async () => 0
4376
+ });
4377
+ registerMetricCollector({
4378
+ name: "avg_latency_ms",
4379
+ category: "performance",
4380
+ unit: "ms",
4381
+ collect: async () => 0
4382
+ });
4383
+
3267
4384
  // src/index.ts
3268
4385
  var DEFAULT_RULES = [
3269
4386
  // --- HTTP Proxy: Dangerous outbound calls ---
@@ -3756,6 +4873,7 @@ var index_default = PolicyEngine;
3756
4873
  AdaptiveThresholdManager,
3757
4874
  AutoHardenEngine,
3758
4875
  ContextAccelerator,
4876
+ ContributionSettlementEngine,
3759
4877
  CostGateEnhancedEngine,
3760
4878
  DEFAULT_CA_CONFIG,
3761
4879
  DEFAULT_GE_CONFIG,
@@ -3767,12 +4885,16 @@ var index_default = PolicyEngine;
3767
4885
  FeatureSwitchesManager,
3768
4886
  GovernanceEnhancer,
3769
4887
  MultiLevelBudgetEngine,
4888
+ OverrideDriftAnalyzer,
3770
4889
  PolicyEngine,
3771
4890
  PricingRulesEngine,
3772
4891
  RecalculationEngine,
3773
4892
  SOVR_FEATURE_SWITCHES,
4893
+ SelfConstraintEngine,
3774
4894
  SemanticDriftDetectorEngine,
4895
+ TIME_WINDOWS,
3775
4896
  TimeSeriesAggregator,
4897
+ TrendAlertEngine,
3776
4898
  TwoPhaseRouter,
3777
4899
  ValuationModel,
3778
4900
  compileFromJSON,