tryassay 0.34.0 → 0.35.1
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/bayesian/__tests__/bas-calculator.test.d.ts +1 -0
- package/dist/bayesian/__tests__/bas-calculator.test.js +63 -0
- package/dist/bayesian/__tests__/bas-calculator.test.js.map +1 -0
- package/dist/bayesian/__tests__/structural-entropy.test.d.ts +1 -0
- package/dist/bayesian/__tests__/structural-entropy.test.js +21 -0
- package/dist/bayesian/__tests__/structural-entropy.test.js.map +1 -0
- package/dist/bayesian/bas-calculator.d.ts +41 -0
- package/dist/bayesian/bas-calculator.js +198 -0
- package/dist/bayesian/bas-calculator.js.map +1 -0
- package/dist/bayesian/index.d.ts +3 -0
- package/dist/bayesian/index.js +3 -0
- package/dist/bayesian/index.js.map +1 -0
- package/dist/bayesian/structural-entropy.d.ts +12 -0
- package/dist/bayesian/structural-entropy.js +37 -0
- package/dist/bayesian/structural-entropy.js.map +1 -0
- package/dist/bayesian/types.d.ts +37 -0
- package/dist/bayesian/types.js +6 -0
- package/dist/bayesian/types.js.map +1 -0
- package/dist/cli.js +28 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/__tests__/assess-formal.test.d.ts +1 -0
- package/dist/commands/__tests__/assess-formal.test.js +72 -0
- package/dist/commands/__tests__/assess-formal.test.js.map +1 -0
- package/dist/commands/activate.d.ts +1 -0
- package/dist/commands/activate.js +48 -0
- package/dist/commands/activate.js.map +1 -0
- package/dist/commands/assess.js +100 -5
- package/dist/commands/assess.js.map +1 -1
- package/dist/commands/bas-score.d.ts +13 -0
- package/dist/commands/bas-score.js +310 -0
- package/dist/commands/bas-score.js.map +1 -0
- package/dist/commands/bounty-watch.js.map +1 -1
- package/dist/commands/hunt.js +32 -0
- package/dist/commands/hunt.js.map +1 -1
- package/dist/commands/runtime.js +11 -10
- package/dist/commands/runtime.js.map +1 -1
- package/dist/commands/stream-verify.d.ts +16 -0
- package/dist/commands/stream-verify.js +228 -0
- package/dist/commands/stream-verify.js.map +1 -0
- package/dist/commands/watch.js.map +1 -1
- package/dist/hunt/__tests__/deep-dive.test.js.map +1 -1
- package/dist/hunt/__tests__/e2e.test.js.map +1 -1
- package/dist/hunt/__tests__/finding-to-template.test.js +10 -1
- package/dist/hunt/__tests__/finding-to-template.test.js.map +1 -1
- package/dist/hunt/__tests__/orchestrator.test.js.map +1 -1
- package/dist/hunt/__tests__/templates.test.js +2 -2
- package/dist/hunt/__tests__/triage.test.js.map +1 -1
- package/dist/hunt/deep-dive.js +7 -7
- package/dist/hunt/deep-dive.js.map +1 -1
- package/dist/hunt/parse-utils.d.ts +1 -1
- package/dist/hunt/state.js.map +1 -1
- package/dist/hunt/templates/injection.js +1 -1
- package/dist/hunt/templates/injection.js.map +1 -1
- package/dist/hunt/triage.js +5 -5
- package/dist/hunt/triage.js.map +1 -1
- package/dist/lib/__tests__/arithmetic-quick-test.js +10 -9
- package/dist/lib/__tests__/arithmetic-quick-test.js.map +1 -1
- package/dist/lib/__tests__/arithmetic-real-llm-test.js +8 -8
- package/dist/lib/__tests__/arithmetic-real-llm-test.js.map +1 -1
- package/dist/lib/__tests__/formal-verifier-api-misuse.test.js +4 -3
- package/dist/lib/__tests__/formal-verifier-api-misuse.test.js.map +1 -1
- package/dist/lib/__tests__/formal-verifier-behavioral.test.d.ts +18 -0
- package/dist/lib/__tests__/formal-verifier-behavioral.test.js +576 -0
- package/dist/lib/__tests__/formal-verifier-behavioral.test.js.map +1 -0
- package/dist/lib/__tests__/formal-verifier-claimless-async.test.d.ts +1 -0
- package/dist/lib/__tests__/formal-verifier-claimless-async.test.js +154 -0
- package/dist/lib/__tests__/formal-verifier-claimless-async.test.js.map +1 -0
- package/dist/lib/__tests__/formal-verifier-claimless-quality.test.d.ts +1 -0
- package/dist/lib/__tests__/formal-verifier-claimless-quality.test.js +121 -0
- package/dist/lib/__tests__/formal-verifier-claimless-quality.test.js.map +1 -0
- package/dist/lib/__tests__/formal-verifier-claimless-realworld.test.d.ts +1 -0
- package/dist/lib/__tests__/formal-verifier-claimless-realworld.test.js +119 -0
- package/dist/lib/__tests__/formal-verifier-claimless-realworld.test.js.map +1 -0
- package/dist/lib/__tests__/formal-verifier-claimless.test.d.ts +1 -0
- package/dist/lib/__tests__/formal-verifier-claimless.test.js +667 -0
- package/dist/lib/__tests__/formal-verifier-claimless.test.js.map +1 -0
- package/dist/lib/__tests__/mr-gsm8k-benchmark.js +6 -6
- package/dist/lib/__tests__/mr-gsm8k-benchmark.js.map +1 -1
- package/dist/lib/__tests__/pr-harvester.test.js.map +1 -1
- package/dist/lib/assessment-reporter.d.ts +1 -1
- package/dist/lib/assessment-reporter.js +2 -1
- package/dist/lib/assessment-reporter.js.map +1 -1
- package/dist/lib/chain-analyzer.d.ts +4 -3
- package/dist/lib/chain-analyzer.js.map +1 -1
- package/dist/lib/formal-verifier.d.ts +20 -1
- package/dist/lib/formal-verifier.js +1182 -24
- package/dist/lib/formal-verifier.js.map +1 -1
- package/dist/lib/issue-reporter.d.ts +2 -1
- package/dist/lib/issue-reporter.js.map +1 -1
- package/dist/lib/remediation-generator.js.map +1 -1
- package/dist/lib/report-generator.js.map +1 -1
- package/dist/lib/rule-harvester/ground-truth.js +13 -2
- package/dist/lib/rule-harvester/ground-truth.js.map +1 -1
- package/dist/lib/rule-harvester/scanner.d.ts +1 -1
- package/dist/lib/user-config.d.ts +1 -0
- package/dist/lib/user-config.js.map +1 -1
- package/dist/realtime/__tests__/entropy-detector.test.d.ts +1 -0
- package/dist/realtime/__tests__/entropy-detector.test.js +200 -0
- package/dist/realtime/__tests__/entropy-detector.test.js.map +1 -0
- package/dist/realtime/__tests__/entropy-live-demo.d.ts +1 -0
- package/dist/realtime/__tests__/entropy-live-demo.js +103 -0
- package/dist/realtime/__tests__/entropy-live-demo.js.map +1 -0
- package/dist/realtime/__tests__/entropy-live.d.ts +8 -0
- package/dist/realtime/__tests__/entropy-live.js +114 -0
- package/dist/realtime/__tests__/entropy-live.js.map +1 -0
- package/dist/realtime/__tests__/streaming-checks.test.js +3 -4
- package/dist/realtime/__tests__/streaming-checks.test.js.map +1 -1
- package/dist/realtime/entropy-detector.d.ts +143 -0
- package/dist/realtime/entropy-detector.js +504 -0
- package/dist/realtime/entropy-detector.js.map +1 -0
- package/dist/realtime/mcp-server.d.ts +7 -1
- package/dist/realtime/mcp-server.js +378 -2
- package/dist/realtime/mcp-server.js.map +1 -1
- package/dist/realtime/stream-interceptor.d.ts +28 -0
- package/dist/realtime/stream-interceptor.js +204 -0
- package/dist/realtime/stream-interceptor.js.map +1 -1
- package/dist/realtime/streaming-checks.js +28 -0
- package/dist/realtime/streaming-checks.js.map +1 -1
- package/dist/realtime/streaming-verifier.d.ts +45 -0
- package/dist/realtime/streaming-verifier.js +98 -5
- package/dist/realtime/streaming-verifier.js.map +1 -1
- package/dist/realtime/types.d.ts +56 -0
- package/dist/runtime/agents/research-agent.js +10 -1
- package/dist/runtime/agents/research-agent.js.map +1 -1
- package/dist/runtime/agents/test-agent.js +10 -7
- package/dist/runtime/agents/test-agent.js.map +1 -1
- package/dist/runtime/composition-verifier.js +13 -3
- package/dist/runtime/composition-verifier.js.map +1 -1
- package/dist/runtime/fs-helpers.js.map +1 -1
- package/dist/runtime/prompt-safety-analyzer.js.map +1 -1
- package/dist/sdk/verified-generate.js.map +1 -1
- package/dist/types.d.ts +14 -0
- package/package.json +3 -2
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entropy-based hallucination detector for real-time streaming verification.
|
|
3
|
+
*
|
|
4
|
+
* Monitors per-token logprob distributions from OpenAI's API and detects
|
|
5
|
+
* hallucination through two complementary strategies:
|
|
6
|
+
*
|
|
7
|
+
* 1. FRACTION-BASED (works on weaker models like GPT-4o-mini):
|
|
8
|
+
* Flags when the fraction of high-entropy tokens exceeds a threshold.
|
|
9
|
+
* Based on "The Laugh" experiment (2026-03-19).
|
|
10
|
+
*
|
|
11
|
+
* 2. DYNAMICS-BASED (works on frontier models like GPT-5.4):
|
|
12
|
+
* Uses entropy variance, derivatives, window variance, logprob gap patterns,
|
|
13
|
+
* and competitive token fractions. Trained on 148 examples, F1=0.87.
|
|
14
|
+
* Key insight: frontier models hallucinate at similar average confidence
|
|
15
|
+
* but with different patterns of confidence fluctuation.
|
|
16
|
+
*
|
|
17
|
+
* The detector runs both strategies and uses the stronger signal.
|
|
18
|
+
*/
|
|
19
|
+
import type { VerificationEvent, CheckSeverity, EntropyContext, BayesianAnomalyScore } from './types.js';
|
|
20
|
+
import type { BASConfig } from '../bayesian/index.js';
|
|
21
|
+
export interface EntropyDetectorOptions {
|
|
22
|
+
/**
|
|
23
|
+
* Per-token entropy threshold. Tokens above this count as "high entropy".
|
|
24
|
+
* Default: 0.5 (calibrated on 148 code verification examples)
|
|
25
|
+
*/
|
|
26
|
+
tokenThreshold?: number;
|
|
27
|
+
/**
|
|
28
|
+
* Fraction of high-entropy tokens in the window that triggers an alert.
|
|
29
|
+
* Default: 0.35 (best F1 with acceptable FPR from tuning sweep)
|
|
30
|
+
*/
|
|
31
|
+
fractionThreshold?: number;
|
|
32
|
+
/** Sliding window size for computing fraction. Default: 32 */
|
|
33
|
+
windowSize?: number;
|
|
34
|
+
/** Minimum tokens before firing (avoid false positives on first few tokens). Default: 16 */
|
|
35
|
+
minTokens?: number;
|
|
36
|
+
/** Severity for entropy findings. Default: 'medium' */
|
|
37
|
+
severity?: CheckSeverity;
|
|
38
|
+
/** Callback for each entropy measurement */
|
|
39
|
+
onEntropy?: (info: EntropyMeasurement) => void;
|
|
40
|
+
/**
|
|
41
|
+
* Dynamics-based detection threshold (0-1). Default: 0.85.
|
|
42
|
+
* Lower = more sensitive (more false positives).
|
|
43
|
+
* Tuned on live GPT-5.4 data: real code scores 56-83%, fake scores 84-99%.
|
|
44
|
+
*/
|
|
45
|
+
dynamicsThreshold?: number;
|
|
46
|
+
/**
|
|
47
|
+
* When true (default), use the legacy dynamics features (logistic regression weights).
|
|
48
|
+
* When false, use BAS when logprobs are available.
|
|
49
|
+
* Allows A/B testing between old and new detection.
|
|
50
|
+
*/
|
|
51
|
+
useLegacyDynamics?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* BAS configuration. When omitted, sensible defaults are used.
|
|
54
|
+
* Only relevant when useLegacyDynamics is false (default).
|
|
55
|
+
*/
|
|
56
|
+
basConfig?: BASConfig;
|
|
57
|
+
}
|
|
58
|
+
export interface EntropyMeasurement {
|
|
59
|
+
token: string;
|
|
60
|
+
tokenIndex: number;
|
|
61
|
+
entropy: number;
|
|
62
|
+
windowEntropy: number;
|
|
63
|
+
exceedsThreshold: boolean;
|
|
64
|
+
/** Dynamics score at this token (0-1, higher = more likely hallucinating) */
|
|
65
|
+
dynamicsScore?: number;
|
|
66
|
+
}
|
|
67
|
+
export interface TokenLogprob {
|
|
68
|
+
token: string;
|
|
69
|
+
logprob: number;
|
|
70
|
+
topLogprobs: Array<{
|
|
71
|
+
token: string;
|
|
72
|
+
logprob: number;
|
|
73
|
+
}>;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Compute Shannon entropy (bits) from a set of logprobs.
|
|
77
|
+
* Normalizes the top-K probabilities to sum to 1 before computing.
|
|
78
|
+
*/
|
|
79
|
+
export declare function computeEntropy(topLogprobs: Array<{
|
|
80
|
+
logprob: number;
|
|
81
|
+
}>): number;
|
|
82
|
+
export declare class EntropyDetector {
|
|
83
|
+
private readonly tokenThreshold;
|
|
84
|
+
private readonly fractionThreshold;
|
|
85
|
+
private readonly windowSize;
|
|
86
|
+
private readonly minTokens;
|
|
87
|
+
private readonly severity;
|
|
88
|
+
private readonly dynamicsThreshold;
|
|
89
|
+
private readonly useLegacyDynamics;
|
|
90
|
+
private readonly onEntropy?;
|
|
91
|
+
private readonly basCalculator;
|
|
92
|
+
private highEntropyWindow;
|
|
93
|
+
private tokenIndex;
|
|
94
|
+
private totalEntropy;
|
|
95
|
+
private alertCount;
|
|
96
|
+
private tokenBuffer;
|
|
97
|
+
private lastAlertIndex;
|
|
98
|
+
private unitEntropies;
|
|
99
|
+
private unitLogprobGaps;
|
|
100
|
+
private unitCompetitiveCount;
|
|
101
|
+
private unitBASResults;
|
|
102
|
+
private allEntropies;
|
|
103
|
+
constructor(options?: EntropyDetectorOptions);
|
|
104
|
+
/** Set language context on the BAS calculator for structural entropy. */
|
|
105
|
+
setBASLanguage(lang: string): void;
|
|
106
|
+
/** Feed prompt tokens to the BAS calculator for repetition confidence. */
|
|
107
|
+
setBASPromptTokens(tokens: string[]): void;
|
|
108
|
+
/**
|
|
109
|
+
* Compute BAS for a single token's logprobs.
|
|
110
|
+
* Returns null when useLegacyDynamics is true, dynamics is explicitly
|
|
111
|
+
* disabled (dynamicsThreshold > 1.0), or no logprobs provided.
|
|
112
|
+
*/
|
|
113
|
+
computeBAS(tokenLogprobs: TokenLogprob): BayesianAnomalyScore | null;
|
|
114
|
+
/**
|
|
115
|
+
* Process a single token with its logprob distribution.
|
|
116
|
+
* Returns a VerificationEvent if either the fraction-based or
|
|
117
|
+
* dynamics-based detector triggers.
|
|
118
|
+
*/
|
|
119
|
+
pushToken(tokenInfo: TokenLogprob): VerificationEvent | null;
|
|
120
|
+
/**
|
|
121
|
+
* Compute dynamics-based hallucination score (0-1).
|
|
122
|
+
* Uses entropy variance, derivatives, window variance, and logprob patterns.
|
|
123
|
+
*/
|
|
124
|
+
private computeDynamicsScore;
|
|
125
|
+
/**
|
|
126
|
+
* Called by the streaming pipeline when a code unit boundary is detected.
|
|
127
|
+
* Returns the entropy context for the tokens that made up that unit,
|
|
128
|
+
* then resets the per-unit accumulator.
|
|
129
|
+
*/
|
|
130
|
+
consumeUnitEntropy(): EntropyContext | undefined;
|
|
131
|
+
/**
|
|
132
|
+
* Compute dynamics score for a specific code unit's features.
|
|
133
|
+
*/
|
|
134
|
+
private computeUnitDynamicsScore;
|
|
135
|
+
/** Get cumulative stats. */
|
|
136
|
+
getStats(): {
|
|
137
|
+
tokensProcessed: number;
|
|
138
|
+
avgEntropy: number;
|
|
139
|
+
alerts: number;
|
|
140
|
+
};
|
|
141
|
+
/** Reset state. */
|
|
142
|
+
reset(): void;
|
|
143
|
+
}
|
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entropy-based hallucination detector for real-time streaming verification.
|
|
3
|
+
*
|
|
4
|
+
* Monitors per-token logprob distributions from OpenAI's API and detects
|
|
5
|
+
* hallucination through two complementary strategies:
|
|
6
|
+
*
|
|
7
|
+
* 1. FRACTION-BASED (works on weaker models like GPT-4o-mini):
|
|
8
|
+
* Flags when the fraction of high-entropy tokens exceeds a threshold.
|
|
9
|
+
* Based on "The Laugh" experiment (2026-03-19).
|
|
10
|
+
*
|
|
11
|
+
* 2. DYNAMICS-BASED (works on frontier models like GPT-5.4):
|
|
12
|
+
* Uses entropy variance, derivatives, window variance, logprob gap patterns,
|
|
13
|
+
* and competitive token fractions. Trained on 148 examples, F1=0.87.
|
|
14
|
+
* Key insight: frontier models hallucinate at similar average confidence
|
|
15
|
+
* but with different patterns of confidence fluctuation.
|
|
16
|
+
*
|
|
17
|
+
* The detector runs both strategies and uses the stronger signal.
|
|
18
|
+
*/
|
|
19
|
+
import { BASCalculator } from '../bayesian/index.js';
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// Entropy computation
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
/**
|
|
24
|
+
* Compute Shannon entropy (bits) from a set of logprobs.
|
|
25
|
+
* Normalizes the top-K probabilities to sum to 1 before computing.
|
|
26
|
+
*/
|
|
27
|
+
export function computeEntropy(topLogprobs) {
|
|
28
|
+
if (topLogprobs.length === 0)
|
|
29
|
+
return 0;
|
|
30
|
+
const probs = topLogprobs.map(t => Math.exp(t.logprob));
|
|
31
|
+
const total = probs.reduce((a, b) => a + b, 0);
|
|
32
|
+
if (total <= 0)
|
|
33
|
+
return 0;
|
|
34
|
+
let entropy = 0;
|
|
35
|
+
for (const p of probs) {
|
|
36
|
+
const normalized = p / total;
|
|
37
|
+
if (normalized > 0) {
|
|
38
|
+
entropy -= normalized * Math.log2(normalized);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return entropy;
|
|
42
|
+
}
|
|
43
|
+
// Simplified: use the top 8 features with approximate coefficients.
|
|
44
|
+
// These approximate the logistic regression trained in analyze_gpt5.py.
|
|
45
|
+
// The weights are directional: positive = more hallucination-like.
|
|
46
|
+
const DYNAMICS_FEATURES = [
|
|
47
|
+
// Window variance features (top 2)
|
|
48
|
+
{ feature: 'win16MaxVar', weight: 0.40, mean: 0.015, std: 0.025 },
|
|
49
|
+
{ feature: 'win32MaxVar', weight: 0.38, mean: 0.012, std: 0.020 },
|
|
50
|
+
// Entropy std
|
|
51
|
+
{ feature: 'entropyStd', weight: 0.30, mean: 0.30, std: 0.15 },
|
|
52
|
+
// Logprob gap variation
|
|
53
|
+
{ feature: 'gapStd', weight: 0.28, mean: 1.5, std: 0.8 },
|
|
54
|
+
// Entropy acceleration
|
|
55
|
+
{ feature: 'accelMax', weight: 0.25, mean: 0.8, std: 0.5 },
|
|
56
|
+
// Fraction above 0.5
|
|
57
|
+
{ feature: 'fracAbove05', weight: 0.24, mean: 0.15, std: 0.12 },
|
|
58
|
+
// Entropy diff mean (token-to-token change)
|
|
59
|
+
{ feature: 'diffMean', weight: 0.17, mean: 0.20, std: 0.10 },
|
|
60
|
+
// Competitive fraction
|
|
61
|
+
{ feature: 'competitiveFrac', weight: 0.15, mean: 0.10, std: 0.08 },
|
|
62
|
+
];
|
|
63
|
+
const DYNAMICS_INTERCEPT = -1.2; // tuned on live GPT-5.4 data — balances false positives vs misses (2026-03-20)
|
|
64
|
+
function sigmoid(x) {
|
|
65
|
+
return 1 / (1 + Math.exp(-x));
|
|
66
|
+
}
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
// EntropyDetector
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
/** Default BAS config — initial weights before calibration on real data. */
|
|
71
|
+
const DEFAULT_BAS_CONFIG = {
|
|
72
|
+
greenThreshold: 0.3,
|
|
73
|
+
redThreshold: 0.7,
|
|
74
|
+
weights: {
|
|
75
|
+
weights: [0.35, 0.25, -0.30, -0.10, 0.20, 0.15, 0.10, 0.20],
|
|
76
|
+
intercept: -0.5,
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
export class EntropyDetector {
|
|
80
|
+
tokenThreshold;
|
|
81
|
+
fractionThreshold;
|
|
82
|
+
windowSize;
|
|
83
|
+
minTokens;
|
|
84
|
+
severity;
|
|
85
|
+
dynamicsThreshold;
|
|
86
|
+
useLegacyDynamics;
|
|
87
|
+
onEntropy;
|
|
88
|
+
// BAS calculator instance (used when useLegacyDynamics is false)
|
|
89
|
+
basCalculator;
|
|
90
|
+
// Sliding window: 1 = high entropy token, 0 = normal token
|
|
91
|
+
highEntropyWindow = [];
|
|
92
|
+
tokenIndex = 0;
|
|
93
|
+
totalEntropy = 0;
|
|
94
|
+
alertCount = 0;
|
|
95
|
+
tokenBuffer = '';
|
|
96
|
+
lastAlertIndex = -1;
|
|
97
|
+
// Per-unit accumulators (consumed at code unit boundaries)
|
|
98
|
+
unitEntropies = [];
|
|
99
|
+
unitLogprobGaps = [];
|
|
100
|
+
unitCompetitiveCount = 0;
|
|
101
|
+
// Per-unit BAS results (consumed at code unit boundaries)
|
|
102
|
+
unitBASResults = [];
|
|
103
|
+
// Full-sequence accumulators for dynamics features
|
|
104
|
+
allEntropies = [];
|
|
105
|
+
constructor(options = {}) {
|
|
106
|
+
this.tokenThreshold = options.tokenThreshold ?? 0.5;
|
|
107
|
+
this.fractionThreshold = options.fractionThreshold ?? 0.35;
|
|
108
|
+
this.windowSize = options.windowSize ?? 32;
|
|
109
|
+
this.minTokens = options.minTokens ?? 16;
|
|
110
|
+
this.severity = options.severity ?? 'medium';
|
|
111
|
+
this.dynamicsThreshold = options.dynamicsThreshold ?? 0.85;
|
|
112
|
+
// Default to legacy dynamics for backward compatibility.
|
|
113
|
+
// Callers opt into BAS by setting useLegacyDynamics: false.
|
|
114
|
+
this.useLegacyDynamics = options.useLegacyDynamics ?? true;
|
|
115
|
+
this.onEntropy = options.onEntropy;
|
|
116
|
+
this.basCalculator = new BASCalculator(options.basConfig ?? DEFAULT_BAS_CONFIG);
|
|
117
|
+
}
|
|
118
|
+
// -- BAS delegation methods ------------------------------------------------
|
|
119
|
+
/** Set language context on the BAS calculator for structural entropy. */
|
|
120
|
+
setBASLanguage(lang) {
|
|
121
|
+
this.basCalculator.setLanguage(lang);
|
|
122
|
+
}
|
|
123
|
+
/** Feed prompt tokens to the BAS calculator for repetition confidence. */
|
|
124
|
+
setBASPromptTokens(tokens) {
|
|
125
|
+
this.basCalculator.setPromptTokens(tokens);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Compute BAS for a single token's logprobs.
|
|
129
|
+
* Returns null when useLegacyDynamics is true, dynamics is explicitly
|
|
130
|
+
* disabled (dynamicsThreshold > 1.0), or no logprobs provided.
|
|
131
|
+
*/
|
|
132
|
+
computeBAS(tokenLogprobs) {
|
|
133
|
+
if (this.useLegacyDynamics)
|
|
134
|
+
return null;
|
|
135
|
+
if (tokenLogprobs.topLogprobs.length === 0)
|
|
136
|
+
return null;
|
|
137
|
+
const basInput = {
|
|
138
|
+
token: tokenLogprobs.token,
|
|
139
|
+
topLogprobs: tokenLogprobs.topLogprobs,
|
|
140
|
+
};
|
|
141
|
+
return this.basCalculator.processToken(basInput);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Process a single token with its logprob distribution.
|
|
145
|
+
* Returns a VerificationEvent if either the fraction-based or
|
|
146
|
+
* dynamics-based detector triggers.
|
|
147
|
+
*/
|
|
148
|
+
pushToken(tokenInfo) {
|
|
149
|
+
const entropy = computeEntropy(tokenInfo.topLogprobs);
|
|
150
|
+
const isHighEntropy = entropy > this.tokenThreshold ? 1 : 0;
|
|
151
|
+
// Update sliding window
|
|
152
|
+
this.highEntropyWindow.push(isHighEntropy);
|
|
153
|
+
if (this.highEntropyWindow.length > this.windowSize) {
|
|
154
|
+
this.highEntropyWindow.shift();
|
|
155
|
+
}
|
|
156
|
+
// Compute fraction of high-entropy tokens in window
|
|
157
|
+
const fraction = this.highEntropyWindow.reduce((a, b) => a + b, 0) / this.highEntropyWindow.length;
|
|
158
|
+
// Track per-unit entropy
|
|
159
|
+
this.unitEntropies.push(entropy);
|
|
160
|
+
this.allEntropies.push(entropy);
|
|
161
|
+
this.totalEntropy += entropy;
|
|
162
|
+
this.tokenIndex++;
|
|
163
|
+
this.tokenBuffer += tokenInfo.token;
|
|
164
|
+
// Track logprob gap (top1 - top2)
|
|
165
|
+
const topLp = tokenInfo.topLogprobs;
|
|
166
|
+
if (topLp.length >= 2) {
|
|
167
|
+
this.unitLogprobGaps.push(topLp[0].logprob - topLp[1].logprob);
|
|
168
|
+
}
|
|
169
|
+
// Track competitive tokens (second choice > 30% of first)
|
|
170
|
+
if (topLp.length >= 2) {
|
|
171
|
+
const p1 = Math.exp(topLp[0].logprob);
|
|
172
|
+
const p2 = Math.exp(topLp[1].logprob);
|
|
173
|
+
if (p1 > 0 && p2 / p1 > 0.3) {
|
|
174
|
+
this.unitCompetitiveCount++;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// --- BAS computation (when enabled) ---
|
|
178
|
+
const basResult = this.computeBAS(tokenInfo);
|
|
179
|
+
if (basResult) {
|
|
180
|
+
this.unitBASResults.push(basResult);
|
|
181
|
+
}
|
|
182
|
+
// --- Dynamics-based detection (GPT-5.4+) ---
|
|
183
|
+
// Primary strategy when we have enough tokens for meaningful stats.
|
|
184
|
+
// When useLegacyDynamics is false and BAS is available, BAS takes priority.
|
|
185
|
+
// A threshold > 1.0 effectively disables dynamics detection.
|
|
186
|
+
const dynamicsEnabled = (this.useLegacyDynamics || !basResult) && this.dynamicsThreshold <= 1.0;
|
|
187
|
+
let dynamicsScore = 0;
|
|
188
|
+
let dynamicsExceeds = false;
|
|
189
|
+
const hasDynamics = dynamicsEnabled && this.allEntropies.length >= this.minTokens;
|
|
190
|
+
if (hasDynamics) {
|
|
191
|
+
dynamicsScore = this.computeDynamicsScore();
|
|
192
|
+
dynamicsExceeds = dynamicsScore > this.dynamicsThreshold;
|
|
193
|
+
}
|
|
194
|
+
// --- BAS-based detection (when BAS is active) ---
|
|
195
|
+
const basExceeds = basResult !== null && basResult.depth === 'red';
|
|
196
|
+
// --- Fraction-based detection (GPT-4o-mini / fallback) ---
|
|
197
|
+
// When dynamics is active and has enough data, it supersedes fraction.
|
|
198
|
+
// Fraction is used when dynamics is disabled or hasn't accumulated enough tokens.
|
|
199
|
+
const fractionExceeds = !hasDynamics && !basExceeds &&
|
|
200
|
+
fraction > this.fractionThreshold &&
|
|
201
|
+
this.tokenIndex >= this.minTokens;
|
|
202
|
+
const exceedsThreshold = fractionExceeds || dynamicsExceeds || basExceeds;
|
|
203
|
+
// Fire measurement callback
|
|
204
|
+
this.onEntropy?.({
|
|
205
|
+
token: tokenInfo.token,
|
|
206
|
+
tokenIndex: this.tokenIndex,
|
|
207
|
+
entropy,
|
|
208
|
+
windowEntropy: fraction,
|
|
209
|
+
exceedsThreshold,
|
|
210
|
+
dynamicsScore,
|
|
211
|
+
});
|
|
212
|
+
if (!exceedsThreshold) {
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
// Debounce: don't fire more than once per window
|
|
216
|
+
if (this.tokenIndex - this.lastAlertIndex < this.windowSize) {
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
this.alertCount++;
|
|
220
|
+
this.lastAlertIndex = this.tokenIndex;
|
|
221
|
+
const codeUnit = {
|
|
222
|
+
text: this.tokenBuffer.slice(-200),
|
|
223
|
+
kind: 'line',
|
|
224
|
+
startOffset: Math.max(0, this.tokenBuffer.length - 200),
|
|
225
|
+
endOffset: this.tokenBuffer.length,
|
|
226
|
+
language: '',
|
|
227
|
+
};
|
|
228
|
+
const method = basExceeds ? 'bas' : dynamicsExceeds ? 'dynamics' : 'fraction';
|
|
229
|
+
const score = basExceeds ? basResult.score : dynamicsExceeds ? dynamicsScore : fraction;
|
|
230
|
+
const evidenceByMethod = {
|
|
231
|
+
bas: `BAS score ${(score * 100).toFixed(0)}% (depth: red) ` +
|
|
232
|
+
`exceeds threshold (method: Bayesian Anomaly Score). ` +
|
|
233
|
+
`Token "${tokenInfo.token}" at position ${this.tokenIndex}. ` +
|
|
234
|
+
`8-feature Bayesian analysis indicates hallucination.`,
|
|
235
|
+
dynamics: `Dynamics score ${(score * 100).toFixed(0)}% exceeds threshold ` +
|
|
236
|
+
`(method: entropy variance/derivatives analysis). ` +
|
|
237
|
+
`Token "${tokenInfo.token}" at position ${this.tokenIndex}. ` +
|
|
238
|
+
`The model's confidence fluctuation pattern matches hallucination.`,
|
|
239
|
+
fraction: `${(score * 100).toFixed(0)}% of tokens in the last ${this.highEntropyWindow.length} ` +
|
|
240
|
+
`have high entropy (>${this.tokenThreshold}), exceeding the ${(this.fractionThreshold * 100).toFixed(0)}% threshold. ` +
|
|
241
|
+
`Token "${tokenInfo.token}" at position ${this.tokenIndex}. ` +
|
|
242
|
+
`The model is showing sustained uncertainty — a hallucination signal.`,
|
|
243
|
+
};
|
|
244
|
+
const suggestionByMethod = {
|
|
245
|
+
bas: 'Bayesian anomaly features (entropy, Gini, modality, structural mismatch) indicate this code is likely hallucinated',
|
|
246
|
+
dynamics: 'hallucination-like confidence fluctuation patterns',
|
|
247
|
+
fraction: 'sustained high uncertainty',
|
|
248
|
+
};
|
|
249
|
+
return {
|
|
250
|
+
type: 'finding',
|
|
251
|
+
codeUnit,
|
|
252
|
+
checkId: 'entropy_hallucination',
|
|
253
|
+
checkName: 'Entropy Hallucination Detector',
|
|
254
|
+
verdict: 'FAIL',
|
|
255
|
+
evidence: evidenceByMethod[method],
|
|
256
|
+
severity: this.severity,
|
|
257
|
+
suggestion: 'Review this code section carefully. The model showed ' +
|
|
258
|
+
suggestionByMethod[method] +
|
|
259
|
+
', suggesting it may be assembling familiar patterns in an incorrect context.',
|
|
260
|
+
latencyMs: 0,
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Compute dynamics-based hallucination score (0-1).
|
|
265
|
+
* Uses entropy variance, derivatives, window variance, and logprob patterns.
|
|
266
|
+
*/
|
|
267
|
+
computeDynamicsScore() {
|
|
268
|
+
const e = this.allEntropies;
|
|
269
|
+
const n = e.length;
|
|
270
|
+
if (n < 4)
|
|
271
|
+
return 0;
|
|
272
|
+
// Entropy std
|
|
273
|
+
const mean = e.reduce((a, b) => a + b, 0) / n;
|
|
274
|
+
const variance = e.reduce((a, v) => a + (v - mean) ** 2, 0) / n;
|
|
275
|
+
const std = Math.sqrt(variance);
|
|
276
|
+
// First derivative (token-to-token changes)
|
|
277
|
+
const diffs = [];
|
|
278
|
+
for (let i = 1; i < n; i++) {
|
|
279
|
+
diffs.push(Math.abs(e[i] - e[i - 1]));
|
|
280
|
+
}
|
|
281
|
+
const diffMean = diffs.length > 0
|
|
282
|
+
? diffs.reduce((a, b) => a + b, 0) / diffs.length : 0;
|
|
283
|
+
// Second derivative (acceleration)
|
|
284
|
+
let accelMax = 0;
|
|
285
|
+
if (diffs.length > 1) {
|
|
286
|
+
for (let i = 1; i < diffs.length; i++) {
|
|
287
|
+
const accel = Math.abs(diffs[i] - diffs[i - 1]);
|
|
288
|
+
if (accel > accelMax)
|
|
289
|
+
accelMax = accel;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
// Window max variance (16-token windows)
|
|
293
|
+
let win16MaxVar = 0;
|
|
294
|
+
let win32MaxVar = 0;
|
|
295
|
+
if (n >= 16) {
|
|
296
|
+
for (let i = 0; i <= n - 16; i += 8) {
|
|
297
|
+
const window = e.slice(i, i + 16);
|
|
298
|
+
const wMean = window.reduce((a, b) => a + b, 0) / window.length;
|
|
299
|
+
const wVar = window.reduce((a, v) => a + (v - wMean) ** 2, 0) / window.length;
|
|
300
|
+
if (wVar > win16MaxVar)
|
|
301
|
+
win16MaxVar = wVar;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
if (n >= 32) {
|
|
305
|
+
for (let i = 0; i <= n - 32; i += 16) {
|
|
306
|
+
const window = e.slice(i, i + 32);
|
|
307
|
+
const wMean = window.reduce((a, b) => a + b, 0) / window.length;
|
|
308
|
+
const wVar = window.reduce((a, v) => a + (v - wMean) ** 2, 0) / window.length;
|
|
309
|
+
if (wVar > win32MaxVar)
|
|
310
|
+
win32MaxVar = wVar;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
// Logprob gap std
|
|
314
|
+
const gaps = this.unitLogprobGaps;
|
|
315
|
+
let gapStd = 0;
|
|
316
|
+
if (gaps.length > 1) {
|
|
317
|
+
const gapMean = gaps.reduce((a, b) => a + b, 0) / gaps.length;
|
|
318
|
+
const gapVar = gaps.reduce((a, v) => a + (v - gapMean) ** 2, 0) / gaps.length;
|
|
319
|
+
gapStd = Math.sqrt(gapVar);
|
|
320
|
+
}
|
|
321
|
+
// Fraction above 0.5
|
|
322
|
+
const fracAbove05 = e.filter(v => v > 0.5).length / n;
|
|
323
|
+
// Competitive fraction
|
|
324
|
+
const competitiveFrac = this.tokenIndex > 0
|
|
325
|
+
? this.unitCompetitiveCount / this.tokenIndex : 0;
|
|
326
|
+
// Compute weighted score using logistic regression weights
|
|
327
|
+
const featureValues = {
|
|
328
|
+
win16MaxVar,
|
|
329
|
+
win32MaxVar,
|
|
330
|
+
entropyStd: std,
|
|
331
|
+
gapStd,
|
|
332
|
+
accelMax,
|
|
333
|
+
fracAbove05,
|
|
334
|
+
diffMean,
|
|
335
|
+
competitiveFrac,
|
|
336
|
+
};
|
|
337
|
+
let logit = DYNAMICS_INTERCEPT;
|
|
338
|
+
for (const fw of DYNAMICS_FEATURES) {
|
|
339
|
+
const raw = featureValues[fw.feature] ?? 0;
|
|
340
|
+
const zScored = fw.std > 0 ? (raw - fw.mean) / fw.std : 0;
|
|
341
|
+
logit += fw.weight * zScored;
|
|
342
|
+
}
|
|
343
|
+
return sigmoid(logit);
|
|
344
|
+
}
|
|
345
|
+
// -- Per-code-unit entropy accumulation ----------------------------------
|
|
346
|
+
/**
|
|
347
|
+
* Called by the streaming pipeline when a code unit boundary is detected.
|
|
348
|
+
* Returns the entropy context for the tokens that made up that unit,
|
|
349
|
+
* then resets the per-unit accumulator.
|
|
350
|
+
*/
|
|
351
|
+
consumeUnitEntropy() {
|
|
352
|
+
if (this.unitEntropies.length === 0)
|
|
353
|
+
return undefined;
|
|
354
|
+
const entropies = this.unitEntropies;
|
|
355
|
+
const gaps = this.unitLogprobGaps;
|
|
356
|
+
const competitiveCount = this.unitCompetitiveCount;
|
|
357
|
+
const basResults = this.unitBASResults;
|
|
358
|
+
this.unitEntropies = [];
|
|
359
|
+
this.unitLogprobGaps = [];
|
|
360
|
+
this.unitCompetitiveCount = 0;
|
|
361
|
+
this.unitBASResults = [];
|
|
362
|
+
const n = entropies.length;
|
|
363
|
+
const mean = entropies.reduce((a, b) => a + b, 0) / n;
|
|
364
|
+
const highCount = entropies.filter(e => e > this.tokenThreshold).length;
|
|
365
|
+
const fraction = highCount / n;
|
|
366
|
+
const max = Math.max(...entropies);
|
|
367
|
+
// Entropy std
|
|
368
|
+
const variance = entropies.reduce((a, v) => a + (v - mean) ** 2, 0) / n;
|
|
369
|
+
const std = Math.sqrt(variance);
|
|
370
|
+
// First derivative stats
|
|
371
|
+
const diffs = [];
|
|
372
|
+
for (let i = 1; i < n; i++) {
|
|
373
|
+
diffs.push(Math.abs(entropies[i] - entropies[i - 1]));
|
|
374
|
+
}
|
|
375
|
+
const diffMean = diffs.length > 0 ? diffs.reduce((a, b) => a + b, 0) / diffs.length : 0;
|
|
376
|
+
const diffMax = diffs.length > 0 ? Math.max(...diffs) : 0;
|
|
377
|
+
// Second derivative
|
|
378
|
+
let accelMean = 0;
|
|
379
|
+
if (diffs.length > 1) {
|
|
380
|
+
const accels = [];
|
|
381
|
+
for (let i = 1; i < diffs.length; i++) {
|
|
382
|
+
accels.push(Math.abs(diffs[i] - diffs[i - 1]));
|
|
383
|
+
}
|
|
384
|
+
accelMean = accels.reduce((a, b) => a + b, 0) / accels.length;
|
|
385
|
+
}
|
|
386
|
+
// Window max variance (16-token windows within this unit)
|
|
387
|
+
let windowMaxVariance = 0;
|
|
388
|
+
if (n >= 16) {
|
|
389
|
+
for (let i = 0; i <= n - 16; i += 8) {
|
|
390
|
+
const w = entropies.slice(i, i + 16);
|
|
391
|
+
const wMean = w.reduce((a, b) => a + b, 0) / w.length;
|
|
392
|
+
const wVar = w.reduce((a, v) => a + (v - wMean) ** 2, 0) / w.length;
|
|
393
|
+
if (wVar > windowMaxVariance)
|
|
394
|
+
windowMaxVariance = wVar;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
// Logprob gap std
|
|
398
|
+
let logprobGapStd = 0;
|
|
399
|
+
if (gaps.length > 1) {
|
|
400
|
+
const gapMean = gaps.reduce((a, b) => a + b, 0) / gaps.length;
|
|
401
|
+
const gapVar = gaps.reduce((a, v) => a + (v - gapMean) ** 2, 0) / gaps.length;
|
|
402
|
+
logprobGapStd = Math.sqrt(gapVar);
|
|
403
|
+
}
|
|
404
|
+
// Competitive fraction
|
|
405
|
+
const competitiveFraction = n > 0 ? competitiveCount / n : 0;
|
|
406
|
+
// Compute dynamics score for this unit
|
|
407
|
+
const dynamicsScore = this.computeUnitDynamicsScore({
|
|
408
|
+
entropyStd: std,
|
|
409
|
+
diffMean,
|
|
410
|
+
accelMax: diffs.length > 1 ? Math.max(...diffs.slice(1).map((d, i) => Math.abs(d - diffs[i]))) : 0,
|
|
411
|
+
win16MaxVar: windowMaxVariance,
|
|
412
|
+
win32MaxVar: 0, // units are usually smaller than 32 tokens
|
|
413
|
+
gapStd: logprobGapStd,
|
|
414
|
+
fracAbove05: entropies.filter(e => e > 0.5).length / n,
|
|
415
|
+
competitiveFrac: competitiveFraction,
|
|
416
|
+
});
|
|
417
|
+
// Confidence from BOTH signals
|
|
418
|
+
let confidence;
|
|
419
|
+
if (fraction > 0.35 || dynamicsScore > 0.7) {
|
|
420
|
+
confidence = 'low';
|
|
421
|
+
}
|
|
422
|
+
else if (fraction > 0.15 || dynamicsScore > 0.5) {
|
|
423
|
+
confidence = 'medium';
|
|
424
|
+
}
|
|
425
|
+
else {
|
|
426
|
+
confidence = 'high';
|
|
427
|
+
}
|
|
428
|
+
// Aggregate BAS for this unit: average score, use last depth
|
|
429
|
+
let unitBAS;
|
|
430
|
+
let unitDepth;
|
|
431
|
+
if (basResults.length > 0) {
|
|
432
|
+
const avgScore = basResults.reduce((a, b) => a + b.score, 0) / basResults.length;
|
|
433
|
+
const lastBAS = basResults[basResults.length - 1];
|
|
434
|
+
unitBAS = {
|
|
435
|
+
score: avgScore,
|
|
436
|
+
features: lastBAS.features, // representative features from last token
|
|
437
|
+
depth: avgScore < 0.3 ? 'green' : avgScore > 0.7 ? 'red' : 'amber',
|
|
438
|
+
};
|
|
439
|
+
unitDepth = unitBAS.depth;
|
|
440
|
+
// BAS overrides confidence when available
|
|
441
|
+
if (unitBAS.depth === 'red') {
|
|
442
|
+
confidence = 'low';
|
|
443
|
+
}
|
|
444
|
+
else if (unitBAS.depth === 'amber' && confidence === 'high') {
|
|
445
|
+
confidence = 'medium';
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
return {
|
|
449
|
+
meanEntropy: mean,
|
|
450
|
+
highEntropyFraction: fraction,
|
|
451
|
+
maxEntropy: max,
|
|
452
|
+
tokenCount: n,
|
|
453
|
+
confidence,
|
|
454
|
+
// Dynamics features
|
|
455
|
+
entropyStd: std,
|
|
456
|
+
entropyDiffMean: diffMean,
|
|
457
|
+
entropyDiffMax: diffMax,
|
|
458
|
+
entropyAccelMean: accelMean,
|
|
459
|
+
windowMaxVariance,
|
|
460
|
+
logprobGapStd,
|
|
461
|
+
competitiveFraction,
|
|
462
|
+
dynamicsScore,
|
|
463
|
+
// BAS (when logprobs were available)
|
|
464
|
+
bas: unitBAS,
|
|
465
|
+
verificationDepth: unitDepth,
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Compute dynamics score for a specific code unit's features.
|
|
470
|
+
*/
|
|
471
|
+
computeUnitDynamicsScore(features) {
|
|
472
|
+
let logit = DYNAMICS_INTERCEPT;
|
|
473
|
+
for (const fw of DYNAMICS_FEATURES) {
|
|
474
|
+
const raw = features[fw.feature] ?? 0;
|
|
475
|
+
const zScored = fw.std > 0 ? (raw - fw.mean) / fw.std : 0;
|
|
476
|
+
logit += fw.weight * zScored;
|
|
477
|
+
}
|
|
478
|
+
return sigmoid(logit);
|
|
479
|
+
}
|
|
480
|
+
/** Get cumulative stats. */
|
|
481
|
+
getStats() {
|
|
482
|
+
return {
|
|
483
|
+
tokensProcessed: this.tokenIndex,
|
|
484
|
+
avgEntropy: this.tokenIndex > 0 ? this.totalEntropy / this.tokenIndex : 0,
|
|
485
|
+
alerts: this.alertCount,
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
/** Reset state. */
|
|
489
|
+
reset() {
|
|
490
|
+
this.highEntropyWindow = [];
|
|
491
|
+
this.unitEntropies = [];
|
|
492
|
+
this.unitLogprobGaps = [];
|
|
493
|
+
this.unitCompetitiveCount = 0;
|
|
494
|
+
this.unitBASResults = [];
|
|
495
|
+
this.allEntropies = [];
|
|
496
|
+
this.tokenIndex = 0;
|
|
497
|
+
this.totalEntropy = 0;
|
|
498
|
+
this.alertCount = 0;
|
|
499
|
+
this.tokenBuffer = '';
|
|
500
|
+
this.lastAlertIndex = -1;
|
|
501
|
+
this.basCalculator.reset();
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
//# sourceMappingURL=entropy-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entropy-detector.js","sourceRoot":"","sources":["../../src/realtime/entropy-detector.ts"],"names":[],"mappings":"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"}
|