TyrusRC commited on
Commit
165e526
·
verified ·
1 Parent(s): 0360d93

Update root adapter

Browse files
README.md CHANGED
@@ -22,6 +22,25 @@ tags:
22
  base_model: fastino/GLiNER2.5-Decide
23
  metrics:
24
  - accuracy
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  ---
26
 
27
  # TyrusRC/haruspex
@@ -36,8 +55,9 @@ Haruspex **reuses** the published decision encoder
36
  specializes it on security decisions. It does not train a decision model from scratch.
37
 
38
  - Base: `fastino/GLiNER2.5-Decide`.
39
- - Added: a typed decision contract, security specialization data, and a
40
- split-conformal **selective-calibration** layer (accept/abstain against a risk budget).
 
41
  - Serves the TypeSafe `POST /v1/systemone` and native `/v1/evaluate` contracts.
42
 
43
  ## Intended use (security, both sides)
@@ -45,8 +65,10 @@ specializes it on security decisions. It does not train a decision model from sc
45
  - **Offensive (pentest / red-team):** is this template/probe relevant to the target?
46
  is this scanner hit a real finding? finding severity; verdict discipline
47
  (vulnerable / not-vulnerable / inconclusive); attack-path next step.
48
- - **Defensive (SOC / blue-team):** alert triage (true vs false positive), alert
49
- severity/priority, detection-rule applicability, incident routing, CVE applicability.
 
 
50
 
51
  It is a classifier for bounded decisions — not a chatbot, not an exploit generator.
52
 
@@ -69,18 +91,34 @@ haruspex-serve --model TyrusRC/haruspex --port 3000 # POST /v1/systemone
69
 
70
  ## Calibration
71
 
72
- Fitted calibrator: accept threshold `0.999998`, target risk `0.2`, coverage `1.0` (n=129).
73
 
74
- A split-conformal selective layer gates each verdict: it accepts when the top-1
75
- confidence clears a threshold fitted to hold the error AMONG accepted items at a target
76
- risk, and abstains otherwise. Fit it with `python -m haruspex.calibrate`; evaluate
77
- coverage/risk with `python -m haruspex.eval`.
 
 
 
 
 
 
 
 
 
 
 
 
78
 
79
  ## Limitations
80
 
81
  - A specialist for the decision types above; novel free-form judgments belong to a
82
  general LLM.
83
- - Calibrated on the training mix — recalibrate for a very different domain.
84
- - Prediction SETS (not just abstention) await a GLiNER2 fix for per-label scores.
 
 
 
 
85
 
86
  Apache-2.0. Repo + recipe: https://github.com/TyrusRC/haruspex
 
22
  base_model: fastino/GLiNER2.5-Decide
23
  metrics:
24
  - accuracy
25
+ model-index:
26
+ - name: haruspex
27
+ results:
28
+ - task:
29
+ type: text-classification
30
+ name: Security decision (boolean / choice / score)
31
+ dataset:
32
+ type: custom
33
+ name: security pack test split (188 rows)
34
+ metrics:
35
+ - type: accuracy
36
+ value: 0.8777
37
+ name: accuracy
38
+ - type: ece
39
+ value: 0.0353
40
+ name: ece
41
+ - type: brier
42
+ value: 0.0845
43
+ name: brier
44
  ---
45
 
46
  # TyrusRC/haruspex
 
55
  specializes it on security decisions. It does not train a decision model from scratch.
56
 
57
  - Base: `fastino/GLiNER2.5-Decide`.
58
+ - Added: a typed decision contract, security specialization data, a certified
59
+ **selective-calibration** layer (accept/abstain against a risk budget), conformal
60
+ **prediction sets**, and a **novelty gate** that abstains on unfamiliar input.
61
  - Serves the TypeSafe `POST /v1/systemone` and native `/v1/evaluate` contracts.
62
 
63
  ## Intended use (security, both sides)
 
65
  - **Offensive (pentest / red-team):** is this template/probe relevant to the target?
66
  is this scanner hit a real finding? finding severity; verdict discipline
67
  (vulnerable / not-vulnerable / inconclusive); attack-path next step.
68
+ - **Defensive (SOC / blue-team):** alert and incident triage (true / benign / false
69
+ positive), alert severity/priority, detection-rule applicability, incident routing, CVE
70
+ applicability, ATT&CK tactic of Windows/Sysmon events. Raw Defender, Sentinel, Elastic
71
+ ECS and Windows event JSON is normalised before the model reads it.
72
 
73
  It is a classifier for bounded decisions — not a chatbot, not an exploit generator.
74
 
 
91
 
92
  ## Calibration
93
 
94
+ Fitted calibrator: accept threshold `0.8`, target risk `0.2` at delta `0.1`, coverage on the calibration split `0.849057` (n=106), temperature `6.297`.
95
 
96
+ Each verdict carries the full probability distribution over its options (temperature-
97
+ scaled). A Learn-then-Test selective layer accepts a verdict only when its confidence
98
+ clears a threshold certified on a held-out calibration split, so that with probability
99
+ 1 - delta the error among accepted verdicts stays within the target risk; otherwise it
100
+ abstains with `"route": "escalate"`. A conformal prediction set lists the options the
101
+ true answer is among, and a novelty gate abstains on inputs unlike the training data.
102
+ Fit with `python -m haruspex.calibrate` and `python -m haruspex.ood`; evaluate with
103
+ `python -m haruspex.eval`.
104
+
105
+ ## Evaluation
106
+
107
+ Held-out test sets, never used for training, model selection or calibration:
108
+
109
+ - **security pack test split (188 rows)**: accuracy 0.8777, ECE 0.0353, Brier 0.0845; with the calibrator it answers 0.8382 of rows at accuracy 0.931 and abstains on the rest.
110
+
111
+ Comparisons against general LLMs are in the repo's `docs/benchmark.md`.
112
 
113
  ## Limitations
114
 
115
  - A specialist for the decision types above; novel free-form judgments belong to a
116
  general LLM.
117
+ - Calibrated on this domain's held-out split; recalibrate before relying on the
118
+ guarantee on your own data.
119
+ - Prediction-set coverage is marginal over the calibration mix, not per input.
120
+ - A calibrator fitted on a mix of domains holds its risk target on average over that
121
+ mix, not on each domain: check each test set's accepted accuracy under Evaluation,
122
+ and route a domain with its own adapter to that adapter.
123
 
124
  Apache-2.0. Repo + recipe: https://github.com/TyrusRC/haruspex
calibrator.json CHANGED
@@ -1,7 +1,12 @@
1
  {
2
- "threshold": 0.999998,
3
  "target_risk": 0.2,
4
- "achieved_risk": 0.007752,
5
- "coverage": 1.0,
6
- "n": 129
 
 
 
 
 
7
  }
 
1
  {
2
+ "threshold": 0.8,
3
  "target_risk": 0.2,
4
+ "achieved_risk": 0.088889,
5
+ "coverage": 0.849057,
6
+ "n": 106,
7
+ "delta": 0.1,
8
+ "temperature": 6.296538261026657,
9
+ "temperature_scope": "all",
10
+ "set_q": 0.898328,
11
+ "set_alpha": 0.1
12
  }
eval.json CHANGED
@@ -1,7 +1,34 @@
1
  {
2
- "accuracy": 0.8718,
3
- "ece": 0.1076,
4
- "brier": 0.1071,
5
- "test_n": 156,
6
- "dataset": "web held-out"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  }
 
1
  {
2
+ "n": 188,
3
+ "accuracy": 0.8777,
4
+ "accuracy_ci95": [
5
+ 0.8231,
6
+ 0.9171
7
+ ],
8
+ "brier": 0.0845,
9
+ "ece": 0.0353,
10
+ "ece_adaptive": 0.0512,
11
+ "p50_ms": 37.2,
12
+ "by_source": {
13
+ "cve_lookup": {
14
+ "n": 13,
15
+ "accuracy": 1.0
16
+ },
17
+ "model": {
18
+ "n": 173,
19
+ "accuracy": 0.8786
20
+ },
21
+ "model_declined": {
22
+ "n": 2,
23
+ "accuracy": 0.0
24
+ }
25
+ },
26
+ "score_mae": 0.3333,
27
+ "selective": {
28
+ "coverage": 0.8382,
29
+ "accepted_accuracy": 0.931,
30
+ "accepted_risk": 0.069
31
+ },
32
+ "test_n": 188,
33
+ "dataset": "security pack test split"
34
  }
final/adapter_config.json CHANGED
@@ -36,21 +36,21 @@
36
  "revision": null,
37
  "target_modules": [
38
  "project_start.3",
39
- "out_project.3",
40
- "classifier.0",
41
- "project_end.0",
42
- "classifier.2",
43
  "count_pred.0",
 
 
 
44
  "count_pred.2",
45
- "dense",
46
- "projector.0",
47
- "query_proj",
48
  "project_start.0",
49
- "value_proj",
50
  "out_project.0",
51
- "projector.2",
 
52
  "key_proj",
53
- "project_end.3"
 
 
54
  ],
55
  "target_parameters": null,
56
  "task_type": null,
 
36
  "revision": null,
37
  "target_modules": [
38
  "project_start.3",
39
+ "query_proj",
 
 
 
40
  "count_pred.0",
41
+ "projector.2",
42
+ "classifier.2",
43
+ "project_end.0",
44
  "count_pred.2",
 
 
 
45
  "project_start.0",
46
+ "classifier.0",
47
  "out_project.0",
48
+ "value_proj",
49
+ "dense",
50
  "key_proj",
51
+ "out_project.3",
52
+ "project_end.3",
53
+ "projector.0"
54
  ],
55
  "target_parameters": null,
56
  "task_type": null,
final/adapter_model.safetensors CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:e83d73d06ab1fb36313b060a025900e54896bae406d3c072c25edcf28029a471
3
  size 31766440
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6d0947bb4d17a7d949082514600510ca5e96b4c3572283048b1fbfd033fb3643
3
  size 31766440
ood.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"alpha": 0.01, "dim": 2048, "cal_scores": [0.379686, 0.415911, 0.419723, 0.433176, 0.438229, 0.44846, 0.450452, 0.453237, 0.454173, 0.457001, 0.45802, 0.46607, 0.469339, 0.470751, 0.477218, 0.482065, 0.493416, 0.497699, 0.499437, 0.499709, 0.50009, 0.503256, 0.504262, 0.504686, 0.50469, 0.507481, 0.510609, 0.51405, 0.515571, 0.516528, 0.523065, 0.526748, 0.530391, 0.532597, 0.533156, 0.533582, 0.537567, 0.542701, 0.544381, 0.546583, 0.547582, 0.548526, 0.551505, 0.552766, 0.553284, 0.556115, 0.557339, 0.558132, 0.566669, 0.569751, 0.572319, 0.574581, 0.577278, 0.578974, 0.58284, 0.583429, 0.585577, 0.58988, 0.592589, 0.593117, 0.594803, 0.598521, 0.600373, 0.608617, 0.616313, 0.616559, 0.618441, 0.623389, 0.624405, 0.624429, 0.625114, 0.633323, 0.640539, 0.640734, 0.640944, 0.641478, 0.641721, 0.642206, 0.643017, 0.643252, 0.64503, 0.645254, 0.650759, 0.652288, 0.66018, 0.662207, 0.665508, 0.665862, 0.675725, 0.676999, 0.678275, 0.68905, 0.694161, 0.698891, 0.705238, 0.710807, 0.717208, 0.728479, 0.729983, 0.730946, 0.731003, 0.746029, 0.74889, 0.763978, 0.777754, 0.802531, 0.805824, 0.806336, 0.819453, 0.835415, 0.861898, 0.870694, 0.927479]}
ood_train.npy ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1ad1eab461aae248402f4a1c53bf4baa97c991d30806fedd585c139cc57ddea7
3
+ size 1794176