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