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