@principles/core 1.174.0 → 1.175.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/runtime-v2/__tests__/architecture-regression.test.js +39 -0
- package/dist/runtime-v2/__tests__/architecture-regression.test.js.map +1 -1
- package/dist/runtime-v2/detection/__tests__/detection-funnel-policy.test.d.ts +13 -0
- package/dist/runtime-v2/detection/__tests__/detection-funnel-policy.test.d.ts.map +1 -0
- package/dist/runtime-v2/detection/__tests__/detection-funnel-policy.test.js +111 -0
- package/dist/runtime-v2/detection/__tests__/detection-funnel-policy.test.js.map +1 -0
- package/dist/runtime-v2/detection/detection-funnel-policy.d.ts +103 -0
- package/dist/runtime-v2/detection/detection-funnel-policy.d.ts.map +1 -0
- package/dist/runtime-v2/detection/detection-funnel-policy.js +135 -0
- package/dist/runtime-v2/detection/detection-funnel-policy.js.map +1 -0
- package/dist/runtime-v2/detection/index.d.ts +10 -0
- package/dist/runtime-v2/detection/index.d.ts.map +1 -0
- package/dist/runtime-v2/detection/index.js +9 -0
- package/dist/runtime-v2/detection/index.js.map +1 -0
- package/dist/runtime-v2/evidence-triage/__tests__/observation-resolver.test.d.ts +12 -0
- package/dist/runtime-v2/evidence-triage/__tests__/observation-resolver.test.d.ts.map +1 -0
- package/dist/runtime-v2/evidence-triage/__tests__/observation-resolver.test.js +137 -0
- package/dist/runtime-v2/evidence-triage/__tests__/observation-resolver.test.js.map +1 -0
- package/dist/runtime-v2/evidence-triage/__tests__/triage-policy.test.js +104 -1
- package/dist/runtime-v2/evidence-triage/__tests__/triage-policy.test.js.map +1 -1
- package/dist/runtime-v2/evidence-triage/index.d.ts +3 -0
- package/dist/runtime-v2/evidence-triage/index.d.ts.map +1 -1
- package/dist/runtime-v2/evidence-triage/index.js +3 -0
- package/dist/runtime-v2/evidence-triage/index.js.map +1 -1
- package/dist/runtime-v2/evidence-triage/observation-resolver.d.ts +107 -0
- package/dist/runtime-v2/evidence-triage/observation-resolver.d.ts.map +1 -0
- package/dist/runtime-v2/evidence-triage/observation-resolver.js +175 -0
- package/dist/runtime-v2/evidence-triage/observation-resolver.js.map +1 -0
- package/dist/runtime-v2/evidence-triage/triage-policy.d.ts +4 -0
- package/dist/runtime-v2/evidence-triage/triage-policy.d.ts.map +1 -1
- package/dist/runtime-v2/evidence-triage/triage-policy.js +66 -9
- package/dist/runtime-v2/evidence-triage/triage-policy.js.map +1 -1
- package/dist/runtime-v2/evidence-triage/types.d.ts +14 -0
- package/dist/runtime-v2/evidence-triage/types.d.ts.map +1 -1
- package/dist/runtime-v2/evidence-triage/types.js.map +1 -1
- package/dist/runtime-v2/index.d.ts +6 -2
- package/dist/runtime-v2/index.d.ts.map +1 -1
- package/dist/runtime-v2/index.js +3 -1
- package/dist/runtime-v2/index.js.map +1 -1
- package/dist/runtime-v2/pain-gate/__tests__/pain-diagnostic-gate-policy.test.d.ts +15 -0
- package/dist/runtime-v2/pain-gate/__tests__/pain-diagnostic-gate-policy.test.d.ts.map +1 -0
- package/dist/runtime-v2/pain-gate/__tests__/pain-diagnostic-gate-policy.test.js +179 -0
- package/dist/runtime-v2/pain-gate/__tests__/pain-diagnostic-gate-policy.test.js.map +1 -0
- package/dist/runtime-v2/pain-gate/index.d.ts +10 -0
- package/dist/runtime-v2/pain-gate/index.d.ts.map +1 -0
- package/dist/runtime-v2/pain-gate/index.js +9 -0
- package/dist/runtime-v2/pain-gate/index.js.map +1 -0
- package/dist/runtime-v2/pain-gate/pain-diagnostic-gate-policy.d.ts +110 -0
- package/dist/runtime-v2/pain-gate/pain-diagnostic-gate-policy.d.ts.map +1 -0
- package/dist/runtime-v2/pain-gate/pain-diagnostic-gate-policy.js +146 -0
- package/dist/runtime-v2/pain-gate/pain-diagnostic-gate-policy.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pain Diagnostic Gate Policy — PRI-446 (migrated from the plugin adapter)
|
|
3
|
+
*
|
|
4
|
+
* Pure decision logic for pain-diagnostic cooldown and gate evaluation.
|
|
5
|
+
*
|
|
6
|
+
* This module is the single source of truth for the gate's threshold decision
|
|
7
|
+
* tree. It is fully pure: no I/O, no Date.now(), no module-level mutable state.
|
|
8
|
+
* All time and cooldown state is passed in as parameters. The plugin-side
|
|
9
|
+
* pain-diagnostic-gate.ts is now a thin adapter that owns the cooldown Map and
|
|
10
|
+
* feeds Date.now() / the last-diagnosed timestamp into this function.
|
|
11
|
+
*
|
|
12
|
+
* Field precedence / thresholds are copied byte-for-byte from the prior plugin
|
|
13
|
+
* implementation; the plugin's pain-diagnostic-gate.test.ts (40 tests) passes
|
|
14
|
+
* unchanged through the adapter as the equivalence proof.
|
|
15
|
+
*
|
|
16
|
+
* ERR checklist:
|
|
17
|
+
* - ERR-001: inputs validated with Number.isFinite, not `as` casts.
|
|
18
|
+
* - ERR-002: every decision carries reason + detail.
|
|
19
|
+
* - EP-01: source string normalized with a Set membership check.
|
|
20
|
+
*/
|
|
21
|
+
/** Default cooldown window: 15 minutes. */
|
|
22
|
+
export declare const DEFAULT_COOLDOWN_MS: number;
|
|
23
|
+
/** Default pain-trigger threshold. */
|
|
24
|
+
export declare const DEFAULT_PAIN_TRIGGER = 40;
|
|
25
|
+
/** Default high-severity threshold (risky high-score). */
|
|
26
|
+
export declare const DEFAULT_HIGH_SEVERITY = 70;
|
|
27
|
+
/** Default repeated-failure threshold (consecutive errors). */
|
|
28
|
+
export declare const DEFAULT_REPEATED_FAILURE = 4;
|
|
29
|
+
/** Default semantic-pain floor. */
|
|
30
|
+
export declare const DEFAULT_SEMANTIC_PAIN_FLOOR = 60;
|
|
31
|
+
declare const PAIN_DIAGNOSTIC_SOURCES: readonly ["manual", "tool_failure", "dispatch_error", "gate_blocked", "user_empathy", "llm_paralysis", "semantic", "subagent_error"];
|
|
32
|
+
export type PainDiagnosticSource = typeof PAIN_DIAGNOSTIC_SOURCES[number];
|
|
33
|
+
export type PainDiagnosticGateReason = 'manual' | 'high_gfi' | 'repeated_failure' | 'semantic_pain' | 'llm_paralysis' | 'risky_high_score' | 'subagent_error' | 'gate_blocked' | 'cooldown' | 'below_gate';
|
|
34
|
+
export interface PainDiagnosticGateInput {
|
|
35
|
+
source: PainDiagnosticSource | string;
|
|
36
|
+
score: number;
|
|
37
|
+
currentGfi: number;
|
|
38
|
+
consecutiveErrors?: number;
|
|
39
|
+
isRisky?: boolean;
|
|
40
|
+
errorHash?: string;
|
|
41
|
+
sessionId?: string;
|
|
42
|
+
nowMs?: number;
|
|
43
|
+
cooldownMs?: number;
|
|
44
|
+
thresholds?: {
|
|
45
|
+
painTrigger?: number;
|
|
46
|
+
highSeverity?: number;
|
|
47
|
+
highGfi?: number;
|
|
48
|
+
repeatedFailure?: number;
|
|
49
|
+
semanticPain?: number;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export interface PainDiagnosticGateDecision {
|
|
53
|
+
shouldDiagnose: boolean;
|
|
54
|
+
reason: PainDiagnosticGateReason;
|
|
55
|
+
episodeKey: string;
|
|
56
|
+
detail: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Normalize a raw source string to a known PainDiagnosticSource.
|
|
60
|
+
*
|
|
61
|
+
* Unknown sources are passed through unchanged (the caller may still match them
|
|
62
|
+
* against custom thresholds) but flagged via the returned `unknown` flag so the
|
|
63
|
+
* plugin adapter can log it. Core itself does not log.
|
|
64
|
+
*/
|
|
65
|
+
export declare function normalizedSource(source: string): {
|
|
66
|
+
source: PainDiagnosticSource | string;
|
|
67
|
+
unknown: boolean;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Build the episode key that scopes cooldown to a (session, source, hash) triple.
|
|
71
|
+
*/
|
|
72
|
+
export declare function buildEpisodeKey(input: PainDiagnosticGateInput): string;
|
|
73
|
+
/**
|
|
74
|
+
* Evaluate the pure gate decision.
|
|
75
|
+
*
|
|
76
|
+
* @param input - gate input (time in nowMs is the caller's responsibility)
|
|
77
|
+
* @param lastDiagnosedAtMs - the last time this episode was diagnosed, or undefined
|
|
78
|
+
* if never. Provided by the plugin adapter which owns the cooldown Map.
|
|
79
|
+
* @returns the gate decision. If shouldDiagnose is true, the caller MUST record
|
|
80
|
+
* nowMs against this episode (the plugin adapter does this in markDiagnosed).
|
|
81
|
+
*
|
|
82
|
+
* Note on the "unknown source" side effect: the prior plugin implementation
|
|
83
|
+
* logged unknown sources via SystemLogger. Core cannot log, so it surfaces the
|
|
84
|
+
* unknown flag through normalizedSource; the plugin adapter is responsible for
|
|
85
|
+
* logging when it observes an unknown source before calling this function.
|
|
86
|
+
*/
|
|
87
|
+
export declare function evaluatePainDiagnosticGateDecision(input: PainDiagnosticGateInput, lastDiagnosedAtMs?: number): PainDiagnosticGateDecision;
|
|
88
|
+
/**
|
|
89
|
+
* Pure cooldown check for an episode.
|
|
90
|
+
*
|
|
91
|
+
* Used by the trigger controller (PEAT-B2) and re-exported by the plugin adapter
|
|
92
|
+
* as isCooldownActiveForEpisode so its cooldown decision aligns with the gate.
|
|
93
|
+
*/
|
|
94
|
+
export interface CooldownCheckInput {
|
|
95
|
+
/** Source string used to build the episode key. */
|
|
96
|
+
readonly source: string;
|
|
97
|
+
/** Session id used to build the episode key. */
|
|
98
|
+
readonly sessionId?: string;
|
|
99
|
+
/** Error hash used to build the episode key. */
|
|
100
|
+
readonly errorHash?: string;
|
|
101
|
+
/** Cooldown window in ms. Falls back to DEFAULT_COOLDOWN_MS when undefined. */
|
|
102
|
+
readonly cooldownMs?: number;
|
|
103
|
+
/** Current time in ms (caller-injected; core has no clock). */
|
|
104
|
+
readonly nowMs: number;
|
|
105
|
+
/** Last time this episode was diagnosed, or undefined if never. */
|
|
106
|
+
readonly lastDiagnosedAtMs?: number;
|
|
107
|
+
}
|
|
108
|
+
export declare function isCooldownActive(input: CooldownCheckInput): boolean;
|
|
109
|
+
export {};
|
|
110
|
+
//# sourceMappingURL=pain-diagnostic-gate-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pain-diagnostic-gate-policy.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/pain-gate/pain-diagnostic-gate-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,2CAA2C;AAC3C,eAAO,MAAM,mBAAmB,QAAiB,CAAC;AAClD,sCAAsC;AACtC,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,0DAA0D;AAC1D,eAAO,MAAM,qBAAqB,KAAK,CAAC;AACxC,+DAA+D;AAC/D,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAC1C,mCAAmC;AACnC,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAE9C,QAAA,MAAM,uBAAuB,sIASnB,CAAC;AAEX,MAAM,MAAM,oBAAoB,GAAG,OAAO,uBAAuB,CAAC,MAAM,CAAC,CAAC;AAE1E,MAAM,MAAM,wBAAwB,GAChC,QAAQ,GACR,UAAU,GACV,kBAAkB,GAClB,eAAe,GACf,eAAe,GACf,kBAAkB,GAClB,gBAAgB,GAChB,cAAc,GACd,UAAU,GACV,YAAY,CAAC;AAEjB,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,oBAAoB,GAAG,MAAM,CAAC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE;QACX,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;AAED,MAAM,WAAW,0BAA0B;IACzC,cAAc,EAAE,OAAO,CAAC;IACxB,MAAM,EAAE,wBAAwB,CAAC;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB;AAID;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,oBAAoB,GAAG,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAM5G;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,uBAAuB,GAAG,MAAM,CAKtE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,uBAAuB,EAC9B,iBAAiB,CAAC,EAAE,MAAM,GACzB,0BAA0B,CAoE5B;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,mDAAmD;IACnD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,gDAAgD;IAChD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,gDAAgD;IAChD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,+EAA+E;IAC/E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,+DAA+D;IAC/D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACrC;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAKnE"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pain Diagnostic Gate Policy — PRI-446 (migrated from the plugin adapter)
|
|
3
|
+
*
|
|
4
|
+
* Pure decision logic for pain-diagnostic cooldown and gate evaluation.
|
|
5
|
+
*
|
|
6
|
+
* This module is the single source of truth for the gate's threshold decision
|
|
7
|
+
* tree. It is fully pure: no I/O, no Date.now(), no module-level mutable state.
|
|
8
|
+
* All time and cooldown state is passed in as parameters. The plugin-side
|
|
9
|
+
* pain-diagnostic-gate.ts is now a thin adapter that owns the cooldown Map and
|
|
10
|
+
* feeds Date.now() / the last-diagnosed timestamp into this function.
|
|
11
|
+
*
|
|
12
|
+
* Field precedence / thresholds are copied byte-for-byte from the prior plugin
|
|
13
|
+
* implementation; the plugin's pain-diagnostic-gate.test.ts (40 tests) passes
|
|
14
|
+
* unchanged through the adapter as the equivalence proof.
|
|
15
|
+
*
|
|
16
|
+
* ERR checklist:
|
|
17
|
+
* - ERR-001: inputs validated with Number.isFinite, not `as` casts.
|
|
18
|
+
* - ERR-002: every decision carries reason + detail.
|
|
19
|
+
* - EP-01: source string normalized with a Set membership check.
|
|
20
|
+
*/
|
|
21
|
+
// ── Defaults (migrated verbatim; previously inline magic numbers) ──────────
|
|
22
|
+
/** Default cooldown window: 15 minutes. */
|
|
23
|
+
export const DEFAULT_COOLDOWN_MS = 15 * 60 * 1000;
|
|
24
|
+
/** Default pain-trigger threshold. */
|
|
25
|
+
export const DEFAULT_PAIN_TRIGGER = 40;
|
|
26
|
+
/** Default high-severity threshold (risky high-score). */
|
|
27
|
+
export const DEFAULT_HIGH_SEVERITY = 70;
|
|
28
|
+
/** Default repeated-failure threshold (consecutive errors). */
|
|
29
|
+
export const DEFAULT_REPEATED_FAILURE = 4;
|
|
30
|
+
/** Default semantic-pain floor. */
|
|
31
|
+
export const DEFAULT_SEMANTIC_PAIN_FLOOR = 60;
|
|
32
|
+
const PAIN_DIAGNOSTIC_SOURCES = [
|
|
33
|
+
'manual',
|
|
34
|
+
'tool_failure',
|
|
35
|
+
'dispatch_error',
|
|
36
|
+
'gate_blocked',
|
|
37
|
+
'user_empathy',
|
|
38
|
+
'llm_paralysis',
|
|
39
|
+
'semantic',
|
|
40
|
+
'subagent_error',
|
|
41
|
+
];
|
|
42
|
+
// ── Pure helpers ────────────────────────────────────────────────────────────
|
|
43
|
+
/**
|
|
44
|
+
* Normalize a raw source string to a known PainDiagnosticSource.
|
|
45
|
+
*
|
|
46
|
+
* Unknown sources are passed through unchanged (the caller may still match them
|
|
47
|
+
* against custom thresholds) but flagged via the returned `unknown` flag so the
|
|
48
|
+
* plugin adapter can log it. Core itself does not log.
|
|
49
|
+
*/
|
|
50
|
+
export function normalizedSource(source) {
|
|
51
|
+
if (source.startsWith('llm_') && source !== 'llm_paralysis') {
|
|
52
|
+
return { source: 'semantic', unknown: false };
|
|
53
|
+
}
|
|
54
|
+
const isKnown = PAIN_DIAGNOSTIC_SOURCES.includes(source);
|
|
55
|
+
return { source, unknown: !isKnown };
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Build the episode key that scopes cooldown to a (session, source, hash) triple.
|
|
59
|
+
*/
|
|
60
|
+
export function buildEpisodeKey(input) {
|
|
61
|
+
const { source } = normalizedSource(input.source);
|
|
62
|
+
const sessionId = input.sessionId || 'unknown';
|
|
63
|
+
const hash = input.errorHash || 'no-hash';
|
|
64
|
+
return `${sessionId}:${source}:${hash}`;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Evaluate the pure gate decision.
|
|
68
|
+
*
|
|
69
|
+
* @param input - gate input (time in nowMs is the caller's responsibility)
|
|
70
|
+
* @param lastDiagnosedAtMs - the last time this episode was diagnosed, or undefined
|
|
71
|
+
* if never. Provided by the plugin adapter which owns the cooldown Map.
|
|
72
|
+
* @returns the gate decision. If shouldDiagnose is true, the caller MUST record
|
|
73
|
+
* nowMs against this episode (the plugin adapter does this in markDiagnosed).
|
|
74
|
+
*
|
|
75
|
+
* Note on the "unknown source" side effect: the prior plugin implementation
|
|
76
|
+
* logged unknown sources via SystemLogger. Core cannot log, so it surfaces the
|
|
77
|
+
* unknown flag through normalizedSource; the plugin adapter is responsible for
|
|
78
|
+
* logging when it observes an unknown source before calling this function.
|
|
79
|
+
*/
|
|
80
|
+
export function evaluatePainDiagnosticGateDecision(input, lastDiagnosedAtMs) {
|
|
81
|
+
const { source } = normalizedSource(input.source);
|
|
82
|
+
const episodeKey = buildEpisodeKey(input);
|
|
83
|
+
const painTrigger = input.thresholds?.painTrigger ?? DEFAULT_PAIN_TRIGGER;
|
|
84
|
+
const highSeverity = input.thresholds?.highSeverity ?? DEFAULT_HIGH_SEVERITY;
|
|
85
|
+
const highGfi = input.thresholds?.highGfi ?? Math.max(highSeverity, painTrigger + 30);
|
|
86
|
+
const repeatedFailure = input.thresholds?.repeatedFailure ?? DEFAULT_REPEATED_FAILURE;
|
|
87
|
+
const semanticPain = input.thresholds?.semanticPain ?? Math.max(painTrigger, DEFAULT_SEMANTIC_PAIN_FLOOR);
|
|
88
|
+
const score = Number.isFinite(input.score) ? input.score : 0;
|
|
89
|
+
const currentGfi = Number.isFinite(input.currentGfi) ? input.currentGfi : 0;
|
|
90
|
+
const consecutiveErrors = typeof input.consecutiveErrors === 'number' && Number.isFinite(input.consecutiveErrors)
|
|
91
|
+
? input.consecutiveErrors
|
|
92
|
+
: 0;
|
|
93
|
+
const cooldownMs = input.cooldownMs ?? DEFAULT_COOLDOWN_MS;
|
|
94
|
+
const nowMs = input.nowMs ?? 0;
|
|
95
|
+
const withinCooldown = cooldownMs > 0 && lastDiagnosedAtMs !== undefined && nowMs - lastDiagnosedAtMs < cooldownMs;
|
|
96
|
+
const approve = (reason, detail) => {
|
|
97
|
+
if (withinCooldown) {
|
|
98
|
+
return {
|
|
99
|
+
shouldDiagnose: false,
|
|
100
|
+
reason: 'cooldown',
|
|
101
|
+
episodeKey,
|
|
102
|
+
detail: `recently diagnosed; ${detail}`,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
return { shouldDiagnose: true, reason, episodeKey, detail };
|
|
106
|
+
};
|
|
107
|
+
if (source === 'manual') {
|
|
108
|
+
return approve('manual', 'manual pain signal bypasses automatic gate');
|
|
109
|
+
}
|
|
110
|
+
if (source === 'subagent_error' && score >= painTrigger) {
|
|
111
|
+
return approve('subagent_error', `subagent error score ${score} >= ${painTrigger}`);
|
|
112
|
+
}
|
|
113
|
+
if (source === 'llm_paralysis' && score >= painTrigger) {
|
|
114
|
+
return approve('llm_paralysis', `llm paralysis score ${score} >= ${painTrigger}`);
|
|
115
|
+
}
|
|
116
|
+
if (source === 'gate_blocked' && score >= painTrigger) {
|
|
117
|
+
return approve('gate_blocked', `gate blocked score ${score} >= ${painTrigger}`);
|
|
118
|
+
}
|
|
119
|
+
if ((source === 'user_empathy' || source === 'semantic') && score >= semanticPain) {
|
|
120
|
+
return approve('semantic_pain', `semantic pain score ${score} >= ${semanticPain}`);
|
|
121
|
+
}
|
|
122
|
+
if (input.isRisky === true && score >= highSeverity) {
|
|
123
|
+
return approve('risky_high_score', `risky operation score ${score} >= ${highSeverity}`);
|
|
124
|
+
}
|
|
125
|
+
if (consecutiveErrors >= repeatedFailure) {
|
|
126
|
+
return approve('repeated_failure', `consecutive errors ${consecutiveErrors} >= ${repeatedFailure}`);
|
|
127
|
+
}
|
|
128
|
+
if (currentGfi >= highGfi) {
|
|
129
|
+
return approve('high_gfi', `GFI ${currentGfi.toFixed(1)} >= ${highGfi}`);
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
shouldDiagnose: false,
|
|
133
|
+
reason: 'below_gate',
|
|
134
|
+
episodeKey,
|
|
135
|
+
detail: `score=${score}; gfi=${currentGfi.toFixed(1)}; consecutive=${consecutiveErrors}`,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
export function isCooldownActive(input) {
|
|
139
|
+
const effectiveCooldown = input.cooldownMs ?? DEFAULT_COOLDOWN_MS;
|
|
140
|
+
if (effectiveCooldown <= 0)
|
|
141
|
+
return false;
|
|
142
|
+
if (input.lastDiagnosedAtMs === undefined)
|
|
143
|
+
return false;
|
|
144
|
+
return input.nowMs - input.lastDiagnosedAtMs < effectiveCooldown;
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=pain-diagnostic-gate-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pain-diagnostic-gate-policy.js","sourceRoot":"","sources":["../../../src/runtime-v2/pain-gate/pain-diagnostic-gate-policy.ts"],"names":[],"mappings":"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"}
|