@reconai/reflex-core 0.1.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/LICENSE +21 -0
- package/README.md +15 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +73 -0
- package/dist/sirl/detectors/collusion.d.ts +6 -0
- package/dist/sirl/detectors/collusion.d.ts.map +1 -0
- package/dist/sirl/detectors/collusion.js +104 -0
- package/dist/sirl/detectors/conformity.d.ts +6 -0
- package/dist/sirl/detectors/conformity.d.ts.map +1 -0
- package/dist/sirl/detectors/conformity.js +69 -0
- package/dist/sirl/detectors/handoff-drift.d.ts +6 -0
- package/dist/sirl/detectors/handoff-drift.d.ts.map +1 -0
- package/dist/sirl/detectors/handoff-drift.js +79 -0
- package/dist/sirl/index.d.ts +8 -0
- package/dist/sirl/index.d.ts.map +1 -0
- package/dist/sirl/index.js +23 -0
- package/dist/sirl/normalize.d.ts +6 -0
- package/dist/sirl/normalize.d.ts.map +1 -0
- package/dist/sirl/normalize.js +20 -0
- package/dist/sirl/policies.d.ts +6 -0
- package/dist/sirl/policies.d.ts.map +1 -0
- package/dist/sirl/policies.js +29 -0
- package/dist/sirl/scoring.d.ts +24 -0
- package/dist/sirl/scoring.d.ts.map +1 -0
- package/dist/sirl/scoring.js +115 -0
- package/dist/sirl/types.d.ts +114 -0
- package/dist/sirl/types.d.ts.map +1 -0
- package/dist/sirl/types.js +29 -0
- package/dist/sirl.d.ts +95 -0
- package/dist/sirl.d.ts.map +1 -0
- package/dist/sirl.js +63 -0
- package/package.json +25 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ReconAI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# @reconai/reflex-core
|
|
2
|
+
|
|
3
|
+
Reflex scoring and decision classification primitives used by the ReconAI SDK (`@reconai/sdk`).
|
|
4
|
+
|
|
5
|
+
Most applications should depend on **`@reconai/sdk`** instead of this package directly. Use `reflex-core` only if you need the scoring math without the rest of the SDK.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @reconai/reflex-core
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## License
|
|
14
|
+
|
|
15
|
+
MIT — see [LICENSE](./LICENSE).
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export * from "./sirl/index";
|
|
2
|
+
export type ReflexDecision = "EXECUTE" | "EXECUTE_MONITOR" | "RETRY" | "REQUIRE_APPROVAL" | "BLOCK";
|
|
3
|
+
export interface ReflexSignals {
|
|
4
|
+
contextIntegrity: number;
|
|
5
|
+
behavioralConsistency: number;
|
|
6
|
+
toolRisk: number;
|
|
7
|
+
outcomeConfidence: number;
|
|
8
|
+
policyAlignment: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function computeReflexScore(signals: ReflexSignals): number;
|
|
11
|
+
export interface ReflexThresholds {
|
|
12
|
+
executeThreshold: number;
|
|
13
|
+
monitorThreshold: number;
|
|
14
|
+
retryThreshold: number;
|
|
15
|
+
approvalThreshold: number;
|
|
16
|
+
}
|
|
17
|
+
export declare function classifyReflexDecision(score: number): ReflexDecision;
|
|
18
|
+
export declare function classifyReflexDecisionWithThresholds(score: number, thresholds?: Partial<ReflexThresholds>): ReflexDecision;
|
|
19
|
+
export declare function computeAutonomyConfidenceScore(signals: ReflexSignals): number;
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAE7B,MAAM,MAAM,cAAc,GACtB,SAAS,GACT,iBAAiB,GACjB,OAAO,GACP,kBAAkB,GAClB,OAAO,CAAC;AAEZ,MAAM,WAAW,aAAa;IAC5B,gBAAgB,EAAE,MAAM,CAAC;IACzB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;CACzB;AAUD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CASjE;AAED,MAAM,WAAW,gBAAgB;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AASD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,CAEpE;AAED,wBAAgB,oCAAoC,CAClD,KAAK,EAAE,MAAM,EACb,UAAU,GAAE,OAAO,CAAC,gBAAgB,CAAM,GACzC,cAAc,CAOhB;AAWD,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAS7E"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.computeReflexScore = computeReflexScore;
|
|
18
|
+
exports.classifyReflexDecision = classifyReflexDecision;
|
|
19
|
+
exports.classifyReflexDecisionWithThresholds = classifyReflexDecisionWithThresholds;
|
|
20
|
+
exports.computeAutonomyConfidenceScore = computeAutonomyConfidenceScore;
|
|
21
|
+
__exportStar(require("./sirl/index"), exports);
|
|
22
|
+
const WEIGHTS = {
|
|
23
|
+
contextIntegrity: 0.25,
|
|
24
|
+
behavioralConsistency: 0.2,
|
|
25
|
+
toolRisk: 0.15,
|
|
26
|
+
outcomeConfidence: 0.2,
|
|
27
|
+
policyAlignment: 0.2,
|
|
28
|
+
};
|
|
29
|
+
function computeReflexScore(signals) {
|
|
30
|
+
const score = signals.contextIntegrity * WEIGHTS.contextIntegrity +
|
|
31
|
+
signals.behavioralConsistency * WEIGHTS.behavioralConsistency +
|
|
32
|
+
signals.toolRisk * WEIGHTS.toolRisk +
|
|
33
|
+
signals.outcomeConfidence * WEIGHTS.outcomeConfidence +
|
|
34
|
+
signals.policyAlignment * WEIGHTS.policyAlignment;
|
|
35
|
+
return Math.round(Math.min(100, Math.max(0, score)) * 100) / 100;
|
|
36
|
+
}
|
|
37
|
+
const DEFAULT_THRESHOLDS = {
|
|
38
|
+
executeThreshold: 90,
|
|
39
|
+
monitorThreshold: 75,
|
|
40
|
+
retryThreshold: 60,
|
|
41
|
+
approvalThreshold: 40,
|
|
42
|
+
};
|
|
43
|
+
function classifyReflexDecision(score) {
|
|
44
|
+
return classifyReflexDecisionWithThresholds(score, DEFAULT_THRESHOLDS);
|
|
45
|
+
}
|
|
46
|
+
function classifyReflexDecisionWithThresholds(score, thresholds = {}) {
|
|
47
|
+
const t = { ...DEFAULT_THRESHOLDS, ...thresholds };
|
|
48
|
+
if (score >= t.executeThreshold)
|
|
49
|
+
return "EXECUTE";
|
|
50
|
+
if (score >= t.monitorThreshold)
|
|
51
|
+
return "EXECUTE_MONITOR";
|
|
52
|
+
if (score >= t.retryThreshold)
|
|
53
|
+
return "RETRY";
|
|
54
|
+
if (score >= t.approvalThreshold)
|
|
55
|
+
return "REQUIRE_APPROVAL";
|
|
56
|
+
return "BLOCK";
|
|
57
|
+
}
|
|
58
|
+
/** Autonomy Confidence Score (ACS) - weighted signal composite */
|
|
59
|
+
const ACS_WEIGHTS = {
|
|
60
|
+
contextIntegrity: 0.3,
|
|
61
|
+
behavioralConsistency: 0.25,
|
|
62
|
+
policyAlignment: 0.2,
|
|
63
|
+
toolRisk: 0.15,
|
|
64
|
+
outcomeConfidence: 0.1,
|
|
65
|
+
};
|
|
66
|
+
function computeAutonomyConfidenceScore(signals) {
|
|
67
|
+
const score = signals.contextIntegrity * ACS_WEIGHTS.contextIntegrity +
|
|
68
|
+
signals.behavioralConsistency * ACS_WEIGHTS.behavioralConsistency +
|
|
69
|
+
signals.policyAlignment * ACS_WEIGHTS.policyAlignment +
|
|
70
|
+
signals.toolRisk * ACS_WEIGHTS.toolRisk +
|
|
71
|
+
signals.outcomeConfidence * ACS_WEIGHTS.outcomeConfidence;
|
|
72
|
+
return Math.round(Math.min(100, Math.max(0, score)) * 100) / 100;
|
|
73
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { SIRLDetectorInput, SIRLSubscore } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Collusion likelihood from output similarity, low rationale diversity, tight coordination, resource overlap.
|
|
4
|
+
*/
|
|
5
|
+
export declare function detectCollusion(input: SIRLDetectorInput): SIRLSubscore;
|
|
6
|
+
//# sourceMappingURL=collusion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collusion.d.ts","sourceRoot":"","sources":["../../../src/sirl/detectors/collusion.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAoEhE;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,iBAAiB,GAAG,YAAY,CAuCtE"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.detectCollusion = detectCollusion;
|
|
4
|
+
const normalize_1 = require("../normalize");
|
|
5
|
+
function tokenize(text) {
|
|
6
|
+
const t = text.toLowerCase().replace(/[^\w\s]/g, " ").split(/\s+/).filter(Boolean);
|
|
7
|
+
return new Set(t);
|
|
8
|
+
}
|
|
9
|
+
function jaccard(a, b) {
|
|
10
|
+
if (a.size === 0 && b.size === 0)
|
|
11
|
+
return 1;
|
|
12
|
+
let inter = 0;
|
|
13
|
+
for (const x of a) {
|
|
14
|
+
if (b.has(x))
|
|
15
|
+
inter += 1;
|
|
16
|
+
}
|
|
17
|
+
const union = a.size + b.size - inter;
|
|
18
|
+
return union === 0 ? 0 : inter / union;
|
|
19
|
+
}
|
|
20
|
+
function avgPairwiseSimilarity(texts) {
|
|
21
|
+
if (texts.length < 2)
|
|
22
|
+
return 0;
|
|
23
|
+
let sum = 0;
|
|
24
|
+
let n = 0;
|
|
25
|
+
for (let i = 0; i < texts.length; i++) {
|
|
26
|
+
for (let j = i + 1; j < texts.length; j++) {
|
|
27
|
+
sum += jaccard(tokenize(texts[i]), tokenize(texts[j]));
|
|
28
|
+
n += 1;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return n === 0 ? 0 : sum / n;
|
|
32
|
+
}
|
|
33
|
+
function rationaleDiversityScore(rationales) {
|
|
34
|
+
if (rationales.length === 0)
|
|
35
|
+
return 50;
|
|
36
|
+
const words = rationales.join(" ").toLowerCase().split(/\s+/).filter(Boolean);
|
|
37
|
+
if (words.length === 0)
|
|
38
|
+
return 50;
|
|
39
|
+
const unique = new Set(words);
|
|
40
|
+
return (0, normalize_1.clamp100)((unique.size / words.length) * 100);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Temporal coordination: low spread of timestamps in a short window → higher collusion risk.
|
|
44
|
+
*/
|
|
45
|
+
function coordinationTightness(events) {
|
|
46
|
+
if (events.length < 2)
|
|
47
|
+
return 0;
|
|
48
|
+
const ms = events.map((e) => new Date(e.timestamp).getTime()).sort((a, b) => a - b);
|
|
49
|
+
const spread = ms[ms.length - 1] - ms[0];
|
|
50
|
+
if (spread <= 0)
|
|
51
|
+
return 100;
|
|
52
|
+
// Under 1s → high risk; over 60s → low
|
|
53
|
+
return (0, normalize_1.clamp100)(100 - Math.min(100, spread / 600));
|
|
54
|
+
}
|
|
55
|
+
function resourceOverlapScore(events) {
|
|
56
|
+
const alloc = events.filter((e) => e.resourceUnits != null && e.resourceUnits > 0);
|
|
57
|
+
if (alloc.length < 2)
|
|
58
|
+
return 0;
|
|
59
|
+
const byAgent = new Map();
|
|
60
|
+
for (const e of alloc) {
|
|
61
|
+
byAgent.set(e.agentId, (byAgent.get(e.agentId) ?? 0) + (e.resourceUnits ?? 0));
|
|
62
|
+
}
|
|
63
|
+
const vals = [...byAgent.values()];
|
|
64
|
+
if (vals.length < 2)
|
|
65
|
+
return 0;
|
|
66
|
+
const max = Math.max(...vals);
|
|
67
|
+
const min = Math.min(...vals);
|
|
68
|
+
if (max === 0)
|
|
69
|
+
return 0;
|
|
70
|
+
return (0, normalize_1.clamp100)((1 - min / max) * 100);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Collusion likelihood from output similarity, low rationale diversity, tight coordination, resource overlap.
|
|
74
|
+
*/
|
|
75
|
+
function detectCollusion(input) {
|
|
76
|
+
const outputs = input.events
|
|
77
|
+
.filter((e) => e.type === "agent_output" && e.outputText && e.outputText.trim().length > 0)
|
|
78
|
+
.map((e) => e.outputText);
|
|
79
|
+
const rationales = input.events
|
|
80
|
+
.map((e) => e.rationaleText)
|
|
81
|
+
.filter((r) => typeof r === "string" && r.length > 0);
|
|
82
|
+
const resourceEvents = input.events.filter((e) => e.type === "resource_allocation");
|
|
83
|
+
const outputSimilarity = (0, normalize_1.clamp100)(avgPairwiseSimilarity(outputs) * 100);
|
|
84
|
+
const diversity = rationaleDiversityScore(rationales);
|
|
85
|
+
const rationaleDiversityRisk = (0, normalize_1.clamp100)(100 - diversity);
|
|
86
|
+
const relevant = input.events.filter((e) => e.type === "agent_output" || e.type === "resource_allocation");
|
|
87
|
+
const coord = coordinationTightness(relevant);
|
|
88
|
+
const resOverlap = resourceOverlapScore(resourceEvents);
|
|
89
|
+
const value = (0, normalize_1.clamp100)(0.35 * outputSimilarity +
|
|
90
|
+
0.25 * coord +
|
|
91
|
+
0.25 * resOverlap +
|
|
92
|
+
0.15 * rationaleDiversityRisk);
|
|
93
|
+
const confidence = (0, normalize_1.clamp100)(Math.min(100, (outputs.length + rationales.length + resourceEvents.length) * 12));
|
|
94
|
+
return {
|
|
95
|
+
value,
|
|
96
|
+
confidence,
|
|
97
|
+
evidence: {
|
|
98
|
+
outputSimilarity,
|
|
99
|
+
rationaleDiversityRisk,
|
|
100
|
+
coordinationTightness: coord,
|
|
101
|
+
resourceOverlap: resOverlap,
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conformity.d.ts","sourceRoot":"","sources":["../../../src/sirl/detectors/conformity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAuBhE;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,iBAAiB,GAAG,YAAY,CAqDvE"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.detectConformity = detectConformity;
|
|
4
|
+
const normalize_1 = require("../normalize");
|
|
5
|
+
function stanceFingerprint(text) {
|
|
6
|
+
const w = text.toLowerCase().split(/\s+/).filter(Boolean).slice(0, 4);
|
|
7
|
+
return w.join("|");
|
|
8
|
+
}
|
|
9
|
+
function wordEntropy(texts) {
|
|
10
|
+
const words = texts.join(" ").toLowerCase().split(/\s+/).filter(Boolean);
|
|
11
|
+
if (words.length === 0)
|
|
12
|
+
return 50;
|
|
13
|
+
const freq = new Map();
|
|
14
|
+
for (const w of words) {
|
|
15
|
+
freq.set(w, (freq.get(w) ?? 0) + 1);
|
|
16
|
+
}
|
|
17
|
+
let h = 0;
|
|
18
|
+
for (const c of freq.values()) {
|
|
19
|
+
const p = c / words.length;
|
|
20
|
+
h -= p * Math.log2(p);
|
|
21
|
+
}
|
|
22
|
+
return (0, normalize_1.clamp100)((h / 8) * 100);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Conformity: dissent collapse, entropy drop, majority echo.
|
|
26
|
+
*/
|
|
27
|
+
function detectConformity(input) {
|
|
28
|
+
const rounds = input.events.filter((e) => e.type === "aggregation_round" || e.type === "agent_output");
|
|
29
|
+
const sorted = [...rounds].sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
|
|
30
|
+
const texts = sorted
|
|
31
|
+
.map((e) => e.outputText ?? e.rationaleText ?? "")
|
|
32
|
+
.filter((t) => t.length > 0);
|
|
33
|
+
if (texts.length < 2) {
|
|
34
|
+
return {
|
|
35
|
+
value: 0,
|
|
36
|
+
confidence: 0,
|
|
37
|
+
evidence: { dissentDrop: 0, entropyDrop: 0, majorityEcho: 0 },
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
const mid = Math.floor(texts.length / 2) || 1;
|
|
41
|
+
const first = texts.slice(0, mid);
|
|
42
|
+
const second = texts.slice(mid);
|
|
43
|
+
const fpFirst = new Set(first.map(stanceFingerprint));
|
|
44
|
+
const fpSecond = new Set(second.map(stanceFingerprint));
|
|
45
|
+
const dissentDrop = fpFirst.size === 0
|
|
46
|
+
? 0
|
|
47
|
+
: (0, normalize_1.clamp100)(Math.max(0, ((fpFirst.size - fpSecond.size) / fpFirst.size) * 100));
|
|
48
|
+
const entFirst = wordEntropy(first);
|
|
49
|
+
const entSecond = wordEntropy(second);
|
|
50
|
+
const entropyDrop = (0, normalize_1.clamp100)(Math.max(0, entFirst - entSecond));
|
|
51
|
+
const allFp = texts.map(stanceFingerprint);
|
|
52
|
+
const counts = new Map();
|
|
53
|
+
for (const f of allFp) {
|
|
54
|
+
counts.set(f, (counts.get(f) ?? 0) + 1);
|
|
55
|
+
}
|
|
56
|
+
const maxC = Math.max(...counts.values());
|
|
57
|
+
const majorityEcho = (0, normalize_1.clamp100)((maxC / allFp.length) * 100);
|
|
58
|
+
const value = (0, normalize_1.clamp100)(0.4 * dissentDrop + 0.35 * entropyDrop + 0.25 * majorityEcho);
|
|
59
|
+
const confidence = (0, normalize_1.clamp100)(Math.min(100, texts.length * 15));
|
|
60
|
+
return {
|
|
61
|
+
value,
|
|
62
|
+
confidence,
|
|
63
|
+
evidence: {
|
|
64
|
+
dissentDrop,
|
|
65
|
+
entropyDrop,
|
|
66
|
+
majorityEcho,
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { SIRLDetectorInput, SIRLSubscore } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Sequential distortion: fact loss, constraint mutation, confidence inflation across handoffs.
|
|
4
|
+
*/
|
|
5
|
+
export declare function detectHandoffDrift(input: SIRLDetectorInput): SIRLSubscore;
|
|
6
|
+
//# sourceMappingURL=handoff-drift.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handoff-drift.d.ts","sourceRoot":"","sources":["../../../src/sirl/detectors/handoff-drift.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAuBhE;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,GAAG,YAAY,CAwDzE"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.detectHandoffDrift = detectHandoffDrift;
|
|
4
|
+
const normalize_1 = require("../normalize");
|
|
5
|
+
function payloadSize(p) {
|
|
6
|
+
if (!p || typeof p !== "object")
|
|
7
|
+
return 0;
|
|
8
|
+
try {
|
|
9
|
+
return JSON.stringify(p).length;
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return 0;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function keyCount(p) {
|
|
16
|
+
if (!p || typeof p !== "object")
|
|
17
|
+
return 0;
|
|
18
|
+
return Object.keys(p).length;
|
|
19
|
+
}
|
|
20
|
+
function textFromPayload(p) {
|
|
21
|
+
const out = p.output ?? p.text ?? p.summary ?? p.body;
|
|
22
|
+
if (typeof out === "string")
|
|
23
|
+
return out;
|
|
24
|
+
return JSON.stringify(p);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Sequential distortion: fact loss, constraint mutation, confidence inflation across handoffs.
|
|
28
|
+
*/
|
|
29
|
+
function detectHandoffDrift(input) {
|
|
30
|
+
const handoffs = [...input.events]
|
|
31
|
+
.filter((e) => e.type === "task_handoff" && e.handoffPayload)
|
|
32
|
+
.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
|
|
33
|
+
if (handoffs.length < 2) {
|
|
34
|
+
return {
|
|
35
|
+
value: 0,
|
|
36
|
+
confidence: handoffs.length === 1 ? 40 : 0,
|
|
37
|
+
evidence: { factLoss: 0, constraintMutation: 0, confidenceInflation: 0 },
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
let factLoss = 0;
|
|
41
|
+
let constraintMutation = 0;
|
|
42
|
+
let confidenceInflation = 0;
|
|
43
|
+
let pairs = 0;
|
|
44
|
+
for (let i = 1; i < handoffs.length; i++) {
|
|
45
|
+
const prev = handoffs[i - 1].handoffPayload;
|
|
46
|
+
const cur = handoffs[i].handoffPayload;
|
|
47
|
+
const prevSize = payloadSize(prev);
|
|
48
|
+
const curSize = payloadSize(cur);
|
|
49
|
+
if (prevSize > 0 && curSize < prevSize) {
|
|
50
|
+
factLoss += (0, normalize_1.clamp100)(((prevSize - curSize) / prevSize) * 100);
|
|
51
|
+
}
|
|
52
|
+
const kPrev = keyCount(prev);
|
|
53
|
+
const kCur = keyCount(cur);
|
|
54
|
+
if (kPrev > 0 && kCur < kPrev) {
|
|
55
|
+
constraintMutation += (0, normalize_1.clamp100)(((kPrev - kCur) / kPrev) * 100);
|
|
56
|
+
}
|
|
57
|
+
const tPrev = textFromPayload(prev).length;
|
|
58
|
+
const tCur = textFromPayload(cur).length;
|
|
59
|
+
if (tCur > tPrev * 1.2 && tCur > 0) {
|
|
60
|
+
confidenceInflation += (0, normalize_1.clamp100)(Math.min(100, ((tCur - tPrev) / tCur) * 100));
|
|
61
|
+
}
|
|
62
|
+
pairs += 1;
|
|
63
|
+
}
|
|
64
|
+
const n = Math.max(1, pairs);
|
|
65
|
+
factLoss = (0, normalize_1.clamp100)(factLoss / n);
|
|
66
|
+
constraintMutation = (0, normalize_1.clamp100)(constraintMutation / n);
|
|
67
|
+
confidenceInflation = (0, normalize_1.clamp100)(confidenceInflation / n);
|
|
68
|
+
const value = (0, normalize_1.clamp100)(0.45 * factLoss + 0.35 * constraintMutation + 0.2 * confidenceInflation);
|
|
69
|
+
const confidence = (0, normalize_1.clamp100)(Math.min(100, handoffs.length * 25));
|
|
70
|
+
return {
|
|
71
|
+
value,
|
|
72
|
+
confidence,
|
|
73
|
+
evidence: {
|
|
74
|
+
factLoss,
|
|
75
|
+
constraintMutation,
|
|
76
|
+
confidenceInflation,
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from "./types";
|
|
2
|
+
export * from "./normalize";
|
|
3
|
+
export * from "./scoring";
|
|
4
|
+
export * from "./policies";
|
|
5
|
+
export * from "./detectors/collusion";
|
|
6
|
+
export * from "./detectors/conformity";
|
|
7
|
+
export * from "./detectors/handoff-drift";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sirl/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./types"), exports);
|
|
18
|
+
__exportStar(require("./normalize"), exports);
|
|
19
|
+
__exportStar(require("./scoring"), exports);
|
|
20
|
+
__exportStar(require("./policies"), exports);
|
|
21
|
+
__exportStar(require("./detectors/collusion"), exports);
|
|
22
|
+
__exportStar(require("./detectors/conformity"), exports);
|
|
23
|
+
__exportStar(require("./detectors/handoff-drift"), exports);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../src/sirl/normalize.ts"],"names":[],"mappings":"AAAA,uBAAuB;AACvB,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAGzC;AAED,yBAAyB;AACzB,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAG1C;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.clamp01 = clamp01;
|
|
4
|
+
exports.clamp100 = clamp100;
|
|
5
|
+
exports.newSirlSignalId = newSirlSignalId;
|
|
6
|
+
/** Clamp to [0, 1]. */
|
|
7
|
+
function clamp01(x) {
|
|
8
|
+
if (Number.isNaN(x) || !Number.isFinite(x))
|
|
9
|
+
return 0;
|
|
10
|
+
return Math.min(1, Math.max(0, x));
|
|
11
|
+
}
|
|
12
|
+
/** Clamp to [0, 100]. */
|
|
13
|
+
function clamp100(x) {
|
|
14
|
+
if (Number.isNaN(x) || !Number.isFinite(x))
|
|
15
|
+
return 0;
|
|
16
|
+
return Math.min(100, Math.max(0, x));
|
|
17
|
+
}
|
|
18
|
+
function newSirlSignalId() {
|
|
19
|
+
return `sirl_sig_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
|
|
20
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { SIRLAnalysisResult, SIRLPolicyDecision } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Threshold-based policy (0–100 scales). Order: freeze → replan → flag → review → observe.
|
|
4
|
+
*/
|
|
5
|
+
export declare function evaluateSIRLPolicies(result: Pick<SIRLAnalysisResult, "subscores" | "dominantPatternType">, collectiveReflexScore: number): SIRLPolicyDecision;
|
|
6
|
+
//# sourceMappingURL=policies.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policies.d.ts","sourceRoot":"","sources":["../../src/sirl/policies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAEtE;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,IAAI,CAAC,kBAAkB,EAAE,WAAW,GAAG,qBAAqB,CAAC,EACrE,qBAAqB,EAAE,MAAM,GAC5B,kBAAkB,CA2BpB"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.evaluateSIRLPolicies = evaluateSIRLPolicies;
|
|
4
|
+
/**
|
|
5
|
+
* Threshold-based policy (0–100 scales). Order: freeze → replan → flag → review → observe.
|
|
6
|
+
*/
|
|
7
|
+
function evaluateSIRLPolicies(result, collectiveReflexScore) {
|
|
8
|
+
const c = result.subscores.collusionLikelihood;
|
|
9
|
+
const f = result.subscores.conformityIndex;
|
|
10
|
+
const h = result.subscores.sequentialDistortionRate;
|
|
11
|
+
const reasons = [];
|
|
12
|
+
if (c.value > 80 && c.confidence > 70) {
|
|
13
|
+
reasons.push("collusion_likelihood_and_confidence_high");
|
|
14
|
+
return { recommendedAction: "FREEZE_CHAIN", reasons };
|
|
15
|
+
}
|
|
16
|
+
if (h.value > 70) {
|
|
17
|
+
reasons.push("handoff_sequential_distortion_high");
|
|
18
|
+
return { recommendedAction: "REPLAN", reasons };
|
|
19
|
+
}
|
|
20
|
+
if (f.value > 65 && collectiveReflexScore < 55) {
|
|
21
|
+
reasons.push("conformity_high_with_low_crs");
|
|
22
|
+
return { recommendedAction: "FLAG", reasons };
|
|
23
|
+
}
|
|
24
|
+
if (collectiveReflexScore < 45) {
|
|
25
|
+
reasons.push("crs_below_threshold");
|
|
26
|
+
return { recommendedAction: "REQUIRE_REVIEW", reasons };
|
|
27
|
+
}
|
|
28
|
+
return { recommendedAction: "OBSERVE", reasons: ["within_thresholds"] };
|
|
29
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { SIRLAnalysisResult, SIRLDetectorInput, SIRLSubscore, TrustCompositeWeights } from "./types";
|
|
2
|
+
/** v1 CRS weights — risk terms 0–1 after dividing subscore.value by 100. */
|
|
3
|
+
export declare const SIRL_CRS_WEIGHTS: {
|
|
4
|
+
readonly collusionLikelihood: 0.3;
|
|
5
|
+
readonly conformityIndex: 0.2;
|
|
6
|
+
readonly sequentialDistortionRate: 0.2;
|
|
7
|
+
readonly resourceSkewScore: 0.15;
|
|
8
|
+
readonly coalitionDriftScore: 0.1;
|
|
9
|
+
readonly silentPropagationRisk: 0.05;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Collective Reflex Score 0–100 from risk subscores (each 0–100).
|
|
13
|
+
*/
|
|
14
|
+
export declare function computeCollectiveReflexScore(subscores: {
|
|
15
|
+
collusionLikelihood: SIRLSubscore;
|
|
16
|
+
conformityIndex: SIRLSubscore;
|
|
17
|
+
sequentialDistortionRate: SIRLSubscore;
|
|
18
|
+
resourceSkewScore?: SIRLSubscore;
|
|
19
|
+
coalitionDriftScore?: SIRLSubscore;
|
|
20
|
+
silentPropagationRisk?: SIRLSubscore;
|
|
21
|
+
}, weights?: Partial<typeof SIRL_CRS_WEIGHTS>): number;
|
|
22
|
+
export declare function computeTrustComposite(individualReflexScore: number, collectiveReflexScore: number, weights?: Partial<TrustCompositeWeights>): number;
|
|
23
|
+
export declare function analyzeSIRL(input: SIRLDetectorInput): SIRLAnalysisResult;
|
|
24
|
+
//# sourceMappingURL=scoring.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scoring.d.ts","sourceRoot":"","sources":["../../src/sirl/scoring.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,kBAAkB,EAClB,iBAAiB,EAIjB,YAAY,EAEZ,qBAAqB,EACtB,MAAM,SAAS,CAAC;AAEjB,4EAA4E;AAC5E,eAAO,MAAM,gBAAgB;;;;;;;CAOnB,CAAC;AAIX;;GAEG;AACH,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE;IACT,mBAAmB,EAAE,YAAY,CAAC;IAClC,eAAe,EAAE,YAAY,CAAC;IAC9B,wBAAwB,EAAE,YAAY,CAAC;IACvC,iBAAiB,CAAC,EAAE,YAAY,CAAC;IACjC,mBAAmB,CAAC,EAAE,YAAY,CAAC;IACnC,qBAAqB,CAAC,EAAE,YAAY,CAAC;CACtC,EACD,OAAO,GAAE,OAAO,CAAC,OAAO,gBAAgB,CAAM,GAC7C,MAAM,CAaR;AAOD,wBAAgB,qBAAqB,CACnC,qBAAqB,EAAE,MAAM,EAC7B,qBAAqB,EAAE,MAAM,EAC7B,OAAO,GAAE,OAAO,CAAC,qBAAqB,CAAM,GAC3C,MAAM,CAOR;AAuED,wBAAgB,WAAW,CAAC,KAAK,EAAE,iBAAiB,GAAG,kBAAkB,CA8BxE"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SIRL_CRS_WEIGHTS = void 0;
|
|
4
|
+
exports.computeCollectiveReflexScore = computeCollectiveReflexScore;
|
|
5
|
+
exports.computeTrustComposite = computeTrustComposite;
|
|
6
|
+
exports.analyzeSIRL = analyzeSIRL;
|
|
7
|
+
const collusion_1 = require("./detectors/collusion");
|
|
8
|
+
const conformity_1 = require("./detectors/conformity");
|
|
9
|
+
const handoff_drift_1 = require("./detectors/handoff-drift");
|
|
10
|
+
const normalize_1 = require("./normalize");
|
|
11
|
+
const policies_1 = require("./policies");
|
|
12
|
+
/** v1 CRS weights — risk terms 0–1 after dividing subscore.value by 100. */
|
|
13
|
+
exports.SIRL_CRS_WEIGHTS = {
|
|
14
|
+
collusionLikelihood: 0.3,
|
|
15
|
+
conformityIndex: 0.2,
|
|
16
|
+
sequentialDistortionRate: 0.2,
|
|
17
|
+
resourceSkewScore: 0.15,
|
|
18
|
+
coalitionDriftScore: 0.1,
|
|
19
|
+
silentPropagationRisk: 0.05,
|
|
20
|
+
};
|
|
21
|
+
const ZERO = { value: 0, confidence: 0, evidence: {} };
|
|
22
|
+
/**
|
|
23
|
+
* Collective Reflex Score 0–100 from risk subscores (each 0–100).
|
|
24
|
+
*/
|
|
25
|
+
function computeCollectiveReflexScore(subscores, weights = {}) {
|
|
26
|
+
const w = { ...exports.SIRL_CRS_WEIGHTS, ...weights };
|
|
27
|
+
const r = (s) => s.value / 100;
|
|
28
|
+
const rawRisk = r(subscores.collusionLikelihood) * w.collusionLikelihood +
|
|
29
|
+
r(subscores.conformityIndex) * w.conformityIndex +
|
|
30
|
+
r(subscores.sequentialDistortionRate) * w.sequentialDistortionRate +
|
|
31
|
+
r(subscores.resourceSkewScore ?? ZERO) * w.resourceSkewScore +
|
|
32
|
+
r(subscores.coalitionDriftScore ?? ZERO) * w.coalitionDriftScore +
|
|
33
|
+
r(subscores.silentPropagationRisk ?? ZERO) * w.silentPropagationRisk;
|
|
34
|
+
const crs = 100 * (1 - Math.min(1, Math.max(0, rawRisk)));
|
|
35
|
+
return Math.round(Math.min(100, Math.max(0, crs)) * 100) / 100;
|
|
36
|
+
}
|
|
37
|
+
const DEFAULT_TRUST_COMPOSITE = {
|
|
38
|
+
individualReflex: 0.6,
|
|
39
|
+
collectiveReflex: 0.4,
|
|
40
|
+
};
|
|
41
|
+
function computeTrustComposite(individualReflexScore, collectiveReflexScore, weights = {}) {
|
|
42
|
+
const w = { ...DEFAULT_TRUST_COMPOSITE, ...weights };
|
|
43
|
+
const sum = w.individualReflex + w.collectiveReflex;
|
|
44
|
+
const n = sum > 0 ? sum : 1;
|
|
45
|
+
const score = (individualReflexScore * w.individualReflex + collectiveReflexScore * w.collectiveReflex) / n;
|
|
46
|
+
return Math.round(Math.min(100, Math.max(0, score)) * 100) / 100;
|
|
47
|
+
}
|
|
48
|
+
function dominantPattern(c, f, h) {
|
|
49
|
+
const scores = [
|
|
50
|
+
{ t: "COLLUSION", v: c.value },
|
|
51
|
+
{ t: "CONFORMITY", v: f.value },
|
|
52
|
+
{ t: "SEQUENTIAL_DISTORTION", v: h.value },
|
|
53
|
+
];
|
|
54
|
+
scores.sort((a, b) => b.v - a.v);
|
|
55
|
+
const top = scores[0];
|
|
56
|
+
if (top.v < 15)
|
|
57
|
+
return null;
|
|
58
|
+
return top.t;
|
|
59
|
+
}
|
|
60
|
+
function buildSignals(input, subscores, action) {
|
|
61
|
+
const ts = new Date().toISOString();
|
|
62
|
+
const agentIds = [...new Set(input.events.map((e) => e.agentId).filter(Boolean))];
|
|
63
|
+
const out = [];
|
|
64
|
+
const push = (patternType, sub, explanation) => {
|
|
65
|
+
if (sub.value < 25 && sub.confidence < 30)
|
|
66
|
+
return;
|
|
67
|
+
out.push({
|
|
68
|
+
id: (0, normalize_1.newSirlSignalId)(),
|
|
69
|
+
orgId: input.orgId,
|
|
70
|
+
missionId: input.missionId,
|
|
71
|
+
taskId: input.taskId ?? null,
|
|
72
|
+
agentIds,
|
|
73
|
+
patternType,
|
|
74
|
+
severity: sub.value / 100,
|
|
75
|
+
confidence: sub.confidence / 100,
|
|
76
|
+
timestamp: ts,
|
|
77
|
+
evidence: {
|
|
78
|
+
outputSimilarity: sub.evidence.outputSimilarity ?? 0,
|
|
79
|
+
dissentDrop: sub.evidence.dissentDrop ?? 0,
|
|
80
|
+
handoffMutationRate: sub.evidence.constraintMutation ?? sub.evidence.factLoss ?? 0,
|
|
81
|
+
resourceSkew: sub.evidence.resourceOverlap ?? 0,
|
|
82
|
+
dependencyDepth: 0,
|
|
83
|
+
clusterDensity: 0,
|
|
84
|
+
},
|
|
85
|
+
explanation,
|
|
86
|
+
recommendedAction: action,
|
|
87
|
+
});
|
|
88
|
+
};
|
|
89
|
+
push("COLLUSION", subscores.collusionLikelihood, "Collusion-like similarity / coordination vs rationale diversity.");
|
|
90
|
+
push("CONFORMITY", subscores.conformityIndex, "Dissent / entropy collapse vs majority echo.");
|
|
91
|
+
push("SEQUENTIAL_DISTORTION", subscores.sequentialDistortionRate, "Handoff payload shrink or constraint loss across relay steps.");
|
|
92
|
+
return out.slice(0, 5);
|
|
93
|
+
}
|
|
94
|
+
function analyzeSIRL(input) {
|
|
95
|
+
const collusionLikelihood = (0, collusion_1.detectCollusion)(input);
|
|
96
|
+
const conformityIndex = (0, conformity_1.detectConformity)(input);
|
|
97
|
+
const sequentialDistortionRate = (0, handoff_drift_1.detectHandoffDrift)(input);
|
|
98
|
+
const subscores = {
|
|
99
|
+
collusionLikelihood,
|
|
100
|
+
conformityIndex,
|
|
101
|
+
sequentialDistortionRate,
|
|
102
|
+
};
|
|
103
|
+
const collectiveReflexScore = computeCollectiveReflexScore(subscores);
|
|
104
|
+
const dominantPatternType = dominantPattern(collusionLikelihood, conformityIndex, sequentialDistortionRate);
|
|
105
|
+
const policy = (0, policies_1.evaluateSIRLPolicies)({ subscores, dominantPatternType }, collectiveReflexScore);
|
|
106
|
+
const signals = buildSignals(input, subscores, policy.recommendedAction);
|
|
107
|
+
return {
|
|
108
|
+
collectiveReflexScore,
|
|
109
|
+
subscores,
|
|
110
|
+
dominantPatternType,
|
|
111
|
+
recommendedAction: policy.recommendedAction,
|
|
112
|
+
policyReasons: policy.reasons,
|
|
113
|
+
signals,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ΔSIRL — Social Intelligence Risk Layer types.
|
|
3
|
+
*/
|
|
4
|
+
export declare const SIRL_PATTERN_TYPES: readonly ["COLLUSION", "CONFORMITY", "RESOURCE_SKEW", "SEQUENTIAL_DISTORTION", "COALITION_DRIFT", "SILENT_PROPAGATION"];
|
|
5
|
+
export type SIRLPatternType = (typeof SIRL_PATTERN_TYPES)[number];
|
|
6
|
+
export declare const SIRL_EVENT_TYPES: readonly ["agent_output", "task_handoff", "resource_allocation", "aggregation_round", "policy_escalation"];
|
|
7
|
+
export type SIRLInteractionEventType = (typeof SIRL_EVENT_TYPES)[number];
|
|
8
|
+
export declare const SIRL_RECOMMENDED_ACTIONS: readonly ["OBSERVE", "FLAG", "REQUIRE_REVIEW", "FREEZE_CHAIN", "SPLIT_CLUSTER", "REPLAN"];
|
|
9
|
+
export type SIRLRecommendedAction = (typeof SIRL_RECOMMENDED_ACTIONS)[number];
|
|
10
|
+
export interface SIRLInteractionEvent {
|
|
11
|
+
orgId: string;
|
|
12
|
+
missionId: string;
|
|
13
|
+
taskId?: string;
|
|
14
|
+
agentId: string;
|
|
15
|
+
agentClusterId?: string;
|
|
16
|
+
type: SIRLInteractionEventType;
|
|
17
|
+
timestamp: string;
|
|
18
|
+
outputText?: string;
|
|
19
|
+
rationaleText?: string;
|
|
20
|
+
handoffPayload?: Record<string, unknown>;
|
|
21
|
+
resourceUnits?: number;
|
|
22
|
+
targetAgentId?: string;
|
|
23
|
+
metadata?: Record<string, unknown>;
|
|
24
|
+
}
|
|
25
|
+
export interface SIRLDetectorInput {
|
|
26
|
+
orgId: string;
|
|
27
|
+
missionId: string;
|
|
28
|
+
taskId?: string;
|
|
29
|
+
windowStart?: string;
|
|
30
|
+
windowEnd?: string;
|
|
31
|
+
events: SIRLInteractionEvent[];
|
|
32
|
+
}
|
|
33
|
+
/** Detector output: value and confidence on 0–100 scale. */
|
|
34
|
+
export interface SIRLSubscore {
|
|
35
|
+
value: number;
|
|
36
|
+
confidence: number;
|
|
37
|
+
evidence: Record<string, number>;
|
|
38
|
+
}
|
|
39
|
+
export interface SIRLSubscores {
|
|
40
|
+
collusionLikelihood: SIRLSubscore;
|
|
41
|
+
conformityIndex: SIRLSubscore;
|
|
42
|
+
sequentialDistortionRate: SIRLSubscore;
|
|
43
|
+
resourceSkewScore?: SIRLSubscore;
|
|
44
|
+
coalitionDriftScore?: SIRLSubscore;
|
|
45
|
+
silentPropagationRisk?: SIRLSubscore;
|
|
46
|
+
}
|
|
47
|
+
export interface SIRLSignalEvidence {
|
|
48
|
+
outputSimilarity: number;
|
|
49
|
+
dissentDrop: number;
|
|
50
|
+
handoffMutationRate: number;
|
|
51
|
+
resourceSkew: number;
|
|
52
|
+
dependencyDepth: number;
|
|
53
|
+
clusterDensity: number;
|
|
54
|
+
}
|
|
55
|
+
export interface SIRLSignal {
|
|
56
|
+
id: string;
|
|
57
|
+
orgId: string;
|
|
58
|
+
missionId: string;
|
|
59
|
+
taskId: string | null;
|
|
60
|
+
agentIds: string[];
|
|
61
|
+
patternType: SIRLPatternType;
|
|
62
|
+
severity: number;
|
|
63
|
+
confidence: number;
|
|
64
|
+
timestamp: string;
|
|
65
|
+
evidence: SIRLSignalEvidence;
|
|
66
|
+
explanation: string;
|
|
67
|
+
recommendedAction: SIRLRecommendedAction;
|
|
68
|
+
}
|
|
69
|
+
export interface SIRLAnalysisResult {
|
|
70
|
+
collectiveReflexScore: number;
|
|
71
|
+
subscores: SIRLSubscores;
|
|
72
|
+
dominantPatternType: SIRLPatternType | null;
|
|
73
|
+
recommendedAction: SIRLRecommendedAction;
|
|
74
|
+
policyReasons: string[];
|
|
75
|
+
signals: SIRLSignal[];
|
|
76
|
+
}
|
|
77
|
+
export interface SIRLPolicyDecision {
|
|
78
|
+
recommendedAction: SIRLRecommendedAction;
|
|
79
|
+
reasons: string[];
|
|
80
|
+
}
|
|
81
|
+
/** Runtime ghost row for dashboards / replay (not necessarily Prisma-shaped). */
|
|
82
|
+
export interface GhostLogSocialEntry {
|
|
83
|
+
id: string;
|
|
84
|
+
orgId: string;
|
|
85
|
+
missionId: string;
|
|
86
|
+
parentEventId: string | null;
|
|
87
|
+
agentClusterId: string;
|
|
88
|
+
interactionPatternType: string;
|
|
89
|
+
collectiveReflexScore: number;
|
|
90
|
+
conformityIndex: number;
|
|
91
|
+
collusionLikelihood: number;
|
|
92
|
+
notes: string;
|
|
93
|
+
timestamp: string;
|
|
94
|
+
}
|
|
95
|
+
export interface PersistedGhostLogSocialEntry {
|
|
96
|
+
id: string;
|
|
97
|
+
orgId: string;
|
|
98
|
+
missionId: string;
|
|
99
|
+
taskId?: string;
|
|
100
|
+
agentClusterId?: string;
|
|
101
|
+
patternType: string;
|
|
102
|
+
collectiveReflexScore: number;
|
|
103
|
+
conformityIndex?: number;
|
|
104
|
+
collusionLikelihood?: number;
|
|
105
|
+
sequentialDistortionRate?: number;
|
|
106
|
+
explanation?: string;
|
|
107
|
+
recommendedAction: string;
|
|
108
|
+
createdAt: string;
|
|
109
|
+
}
|
|
110
|
+
export interface TrustCompositeWeights {
|
|
111
|
+
individualReflex: number;
|
|
112
|
+
collectiveReflex: number;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sirl/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,kBAAkB,yHAOrB,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAElE,eAAO,MAAM,gBAAgB,4GAMnB,CAAC;AAEX,MAAM,MAAM,wBAAwB,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzE,eAAO,MAAM,wBAAwB,2FAO3B,CAAC;AAEX,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9E,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,wBAAwB,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,oBAAoB,EAAE,CAAC;CAChC;AAED,4DAA4D;AAC5D,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,aAAa;IAC5B,mBAAmB,EAAE,YAAY,CAAC;IAClC,eAAe,EAAE,YAAY,CAAC;IAC9B,wBAAwB,EAAE,YAAY,CAAC;IACvC,iBAAiB,CAAC,EAAE,YAAY,CAAC;IACjC,mBAAmB,CAAC,EAAE,YAAY,CAAC;IACnC,qBAAqB,CAAC,EAAE,YAAY,CAAC;CACtC;AAED,MAAM,WAAW,kBAAkB;IACjC,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,EAAE,eAAe,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,qBAAqB,CAAC;CAC1C;AAED,MAAM,WAAW,kBAAkB;IACjC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,SAAS,EAAE,aAAa,CAAC;IACzB,mBAAmB,EAAE,eAAe,GAAG,IAAI,CAAC;IAC5C,iBAAiB,EAAE,qBAAqB,CAAC;IACzC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,OAAO,EAAE,UAAU,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,iBAAiB,EAAE,qBAAqB,CAAC;IACzC,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,iFAAiF;AACjF,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,4BAA4B;IAC3C,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;CAC1B"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ΔSIRL — Social Intelligence Risk Layer types.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SIRL_RECOMMENDED_ACTIONS = exports.SIRL_EVENT_TYPES = exports.SIRL_PATTERN_TYPES = void 0;
|
|
7
|
+
exports.SIRL_PATTERN_TYPES = [
|
|
8
|
+
"COLLUSION",
|
|
9
|
+
"CONFORMITY",
|
|
10
|
+
"RESOURCE_SKEW",
|
|
11
|
+
"SEQUENTIAL_DISTORTION",
|
|
12
|
+
"COALITION_DRIFT",
|
|
13
|
+
"SILENT_PROPAGATION",
|
|
14
|
+
];
|
|
15
|
+
exports.SIRL_EVENT_TYPES = [
|
|
16
|
+
"agent_output",
|
|
17
|
+
"task_handoff",
|
|
18
|
+
"resource_allocation",
|
|
19
|
+
"aggregation_round",
|
|
20
|
+
"policy_escalation",
|
|
21
|
+
];
|
|
22
|
+
exports.SIRL_RECOMMENDED_ACTIONS = [
|
|
23
|
+
"OBSERVE",
|
|
24
|
+
"FLAG",
|
|
25
|
+
"REQUIRE_REVIEW",
|
|
26
|
+
"FREEZE_CHAIN",
|
|
27
|
+
"SPLIT_CLUSTER",
|
|
28
|
+
"REPLAN",
|
|
29
|
+
];
|
package/dist/sirl.d.ts
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Social Intelligence Risk Layer (SIRL) — types and Collective Reflex Score (CRS).
|
|
3
|
+
* Grounded in emergent multi-agent risk: interaction dynamics, not lone-agent alignment.
|
|
4
|
+
*/
|
|
5
|
+
export declare const SIRL_PATTERN_TYPES: readonly ["COLLUSION", "CONFORMITY", "RESOURCE_SKEW", "SEQUENTIAL_DISTORTION", "COALITION_DRIFT", "SILENT_PROPAGATION"];
|
|
6
|
+
export type SIRLPatternType = (typeof SIRL_PATTERN_TYPES)[number];
|
|
7
|
+
export declare const SIRL_RECOMMENDED_ACTIONS: readonly ["OBSERVE", "FLAG", "REQUIRE_REVIEW", "FREEZE_CHAIN", "SPLIT_CLUSTER", "REPLAN"];
|
|
8
|
+
export type SIRLRecommendedAction = (typeof SIRL_RECOMMENDED_ACTIONS)[number];
|
|
9
|
+
/** Subscores in [0, 1]; higher = more risk (except where noted in callers). */
|
|
10
|
+
export interface SIRLSubscores {
|
|
11
|
+
collusionLikelihood: number;
|
|
12
|
+
conformityIndex: number;
|
|
13
|
+
sequentialDistortionRate: number;
|
|
14
|
+
resourceSkewScore: number;
|
|
15
|
+
coalitionDriftScore: number;
|
|
16
|
+
silentPropagationRisk: number;
|
|
17
|
+
}
|
|
18
|
+
/** v1 weights — tune per workflow; sum need not be 1 (they apply to risk terms). */
|
|
19
|
+
export declare const SIRL_CRS_WEIGHTS: {
|
|
20
|
+
readonly collusionLikelihood: 0.3;
|
|
21
|
+
readonly conformityIndex: 0.2;
|
|
22
|
+
readonly sequentialDistortionRate: 0.2;
|
|
23
|
+
readonly resourceSkewScore: 0.15;
|
|
24
|
+
readonly coalitionDriftScore: 0.1;
|
|
25
|
+
readonly silentPropagationRisk: 0.05;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Collective Reflex Score: trust in the interaction pattern, 0–100 (aligned with {@link computeReflexScore}).
|
|
29
|
+
* CRS = 100 * (1 - weighted sum of risk subscores).
|
|
30
|
+
*/
|
|
31
|
+
export declare function computeCollectiveReflexScore(subscores: SIRLSubscores, weights?: Partial<typeof SIRL_CRS_WEIGHTS>): number;
|
|
32
|
+
export interface TrustCompositeWeights {
|
|
33
|
+
individualReflex: number;
|
|
34
|
+
collectiveReflex: number;
|
|
35
|
+
}
|
|
36
|
+
/** IRS and CRS on 0–100; returns 0–100. */
|
|
37
|
+
export declare function computeTrustComposite(individualReflexScore: number, collectiveReflexScore: number, weights?: Partial<TrustCompositeWeights>): number;
|
|
38
|
+
export interface SIRLSignalEvidence {
|
|
39
|
+
outputSimilarity: number;
|
|
40
|
+
dissentDrop: number;
|
|
41
|
+
handoffMutationRate: number;
|
|
42
|
+
resourceSkew: number;
|
|
43
|
+
dependencyDepth: number;
|
|
44
|
+
clusterDensity: number;
|
|
45
|
+
}
|
|
46
|
+
export interface SIRLSignal {
|
|
47
|
+
id: string;
|
|
48
|
+
orgId: string;
|
|
49
|
+
missionId: string;
|
|
50
|
+
taskId: string | null;
|
|
51
|
+
agentIds: string[];
|
|
52
|
+
patternType: SIRLPatternType;
|
|
53
|
+
severity: number;
|
|
54
|
+
confidence: number;
|
|
55
|
+
timestamp: string;
|
|
56
|
+
evidence: SIRLSignalEvidence;
|
|
57
|
+
explanation: string;
|
|
58
|
+
recommendedAction: SIRLRecommendedAction;
|
|
59
|
+
}
|
|
60
|
+
export interface SIRLAnalysisResult {
|
|
61
|
+
collectiveReflexScore: number;
|
|
62
|
+
conformityIndex: number;
|
|
63
|
+
collusionLikelihood: number;
|
|
64
|
+
sequentialDistortionRate: number;
|
|
65
|
+
resourceSkewScore: number;
|
|
66
|
+
coalitionDriftScore: number;
|
|
67
|
+
silentPropagationRisk: number;
|
|
68
|
+
recommendedAction: SIRLRecommendedAction;
|
|
69
|
+
signals: SIRLSignal[];
|
|
70
|
+
}
|
|
71
|
+
export interface SIRLAnalysisRequest {
|
|
72
|
+
orgId: string;
|
|
73
|
+
missionId: string;
|
|
74
|
+
taskId?: string;
|
|
75
|
+
window?: {
|
|
76
|
+
start: string;
|
|
77
|
+
end: string;
|
|
78
|
+
};
|
|
79
|
+
agentIds?: string[];
|
|
80
|
+
}
|
|
81
|
+
/** Optional GhostLog enrichment row for social / multi-agent causal replay. */
|
|
82
|
+
export interface GhostLogSocialEntry {
|
|
83
|
+
id: string;
|
|
84
|
+
orgId: string;
|
|
85
|
+
missionId: string;
|
|
86
|
+
parentEventId: string | null;
|
|
87
|
+
agentClusterId: string;
|
|
88
|
+
interactionPatternType: string;
|
|
89
|
+
collectiveReflexScore: number;
|
|
90
|
+
conformityIndex: number;
|
|
91
|
+
collusionLikelihood: number;
|
|
92
|
+
notes: string;
|
|
93
|
+
timestamp: string;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=sirl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sirl.d.ts","sourceRoot":"","sources":["../src/sirl.ts"],"names":[],"mappings":"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"}
|
package/dist/sirl.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Social Intelligence Risk Layer (SIRL) — types and Collective Reflex Score (CRS).
|
|
4
|
+
* Grounded in emergent multi-agent risk: interaction dynamics, not lone-agent alignment.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.SIRL_CRS_WEIGHTS = exports.SIRL_RECOMMENDED_ACTIONS = exports.SIRL_PATTERN_TYPES = void 0;
|
|
8
|
+
exports.computeCollectiveReflexScore = computeCollectiveReflexScore;
|
|
9
|
+
exports.computeTrustComposite = computeTrustComposite;
|
|
10
|
+
exports.SIRL_PATTERN_TYPES = [
|
|
11
|
+
"COLLUSION",
|
|
12
|
+
"CONFORMITY",
|
|
13
|
+
"RESOURCE_SKEW",
|
|
14
|
+
"SEQUENTIAL_DISTORTION",
|
|
15
|
+
"COALITION_DRIFT",
|
|
16
|
+
"SILENT_PROPAGATION",
|
|
17
|
+
];
|
|
18
|
+
exports.SIRL_RECOMMENDED_ACTIONS = [
|
|
19
|
+
"OBSERVE",
|
|
20
|
+
"FLAG",
|
|
21
|
+
"REQUIRE_REVIEW",
|
|
22
|
+
"FREEZE_CHAIN",
|
|
23
|
+
"SPLIT_CLUSTER",
|
|
24
|
+
"REPLAN",
|
|
25
|
+
];
|
|
26
|
+
/** v1 weights — tune per workflow; sum need not be 1 (they apply to risk terms). */
|
|
27
|
+
exports.SIRL_CRS_WEIGHTS = {
|
|
28
|
+
collusionLikelihood: 0.3,
|
|
29
|
+
conformityIndex: 0.2,
|
|
30
|
+
sequentialDistortionRate: 0.2,
|
|
31
|
+
resourceSkewScore: 0.15,
|
|
32
|
+
coalitionDriftScore: 0.1,
|
|
33
|
+
silentPropagationRisk: 0.05,
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Collective Reflex Score: trust in the interaction pattern, 0–100 (aligned with {@link computeReflexScore}).
|
|
37
|
+
* CRS = 100 * (1 - weighted sum of risk subscores).
|
|
38
|
+
*/
|
|
39
|
+
function computeCollectiveReflexScore(subscores, weights = {}) {
|
|
40
|
+
const w = { ...exports.SIRL_CRS_WEIGHTS, ...weights };
|
|
41
|
+
const rawRisk = subscores.collusionLikelihood * w.collusionLikelihood +
|
|
42
|
+
subscores.conformityIndex * w.conformityIndex +
|
|
43
|
+
subscores.sequentialDistortionRate * w.sequentialDistortionRate +
|
|
44
|
+
subscores.resourceSkewScore * w.resourceSkewScore +
|
|
45
|
+
subscores.coalitionDriftScore * w.coalitionDriftScore +
|
|
46
|
+
subscores.silentPropagationRisk * w.silentPropagationRisk;
|
|
47
|
+
const crs = 100 * (1 - Math.min(1, Math.max(0, rawRisk)));
|
|
48
|
+
return Math.round(Math.min(100, Math.max(0, crs)) * 100) / 100;
|
|
49
|
+
}
|
|
50
|
+
const DEFAULT_TRUST_COMPOSITE = {
|
|
51
|
+
individualReflex: 0.6,
|
|
52
|
+
collectiveReflex: 0.4,
|
|
53
|
+
};
|
|
54
|
+
/** IRS and CRS on 0–100; returns 0–100. */
|
|
55
|
+
function computeTrustComposite(individualReflexScore, collectiveReflexScore, weights = {}) {
|
|
56
|
+
const w = { ...DEFAULT_TRUST_COMPOSITE, ...weights };
|
|
57
|
+
const sum = w.individualReflex + w.collectiveReflex;
|
|
58
|
+
const n = sum > 0 ? sum : 1;
|
|
59
|
+
const score = (individualReflexScore * w.individualReflex +
|
|
60
|
+
collectiveReflexScore * w.collectiveReflex) /
|
|
61
|
+
n;
|
|
62
|
+
return Math.round(Math.min(100, Math.max(0, score)) * 100) / 100;
|
|
63
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@reconai/reflex-core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Reflex score and decision classification primitives for ReconAI.",
|
|
5
|
+
"private": false,
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"README.md",
|
|
12
|
+
"LICENSE"
|
|
13
|
+
],
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"typescript": "^5.3.3",
|
|
19
|
+
"vitest": "^3.0.5"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsc",
|
|
23
|
+
"test": "vitest run"
|
|
24
|
+
}
|
|
25
|
+
}
|