snapkitty
agents
python
SNAPKITTYWEST commited on
Commit
a378387
Β·
verified Β·
1 Parent(s): 30f011f

Sync with GitHub, license metadata from LICENSE files, commercial license notice

Browse files

metadata license: None -> other (snapkitty-tri-license)
README: License section kept (already accurate) + commercial notice
README: GitHub source link added

Files changed (1) hide show
  1. README.md +378 -362
README.md CHANGED
@@ -1,362 +1,378 @@
1
- # BERT Cross-Encoder Entailment Agent
2
-
3
- [![Tests](https://img.shields.io/badge/tests-11%2F11%20passing-brightgreen)](tests/)
4
- [![License: Tri](https://img.shields.io/badge/license-AGPL%20%7C%20BSL%201.1%20%7C%20MIT-blue)](LICENSE)
5
- [![Model: DeBERTa-v3](https://img.shields.io/badge/model-DeBERTa--v3--base-orange)](https://huggingface.co/microsoft/deberta-v3-base)
6
- [![Backend: TensorRT](https://img.shields.io/badge/backend-TensorRT%20FP16-76b900)](https://developer.nvidia.com/tensorrt)
7
- [![Rust](https://img.shields.io/badge/daemon-Rust%20%2F%20Tokio-orange)](daemon/)
8
- [![Audit: BLAKE3+ERE](https://img.shields.io/badge/audit-BLAKE3%20%2B%20ERE%20P5-blueviolet)](agent/ere_gate.py)
9
- [![WORM](https://img.shields.io/badge/ledger-WORM%20chain-critical)](daemon/src/ledger.rs)
10
- [![Lean 4](https://img.shields.io/badge/invariants-Lean%204%20proved-informational)](Invariants.lean)
11
-
12
- **Authors:** Ahmad Ali Parr, Jessica L. Williams (SNAPKITTYWEST)
13
- **Stack:** DeBERTa-v3 Β· ONNX Β· TensorRT FP16 Β· Rust/Tokio Β· BLAKE3 Β· WORM ledger Β· ERE P1-P5
14
-
15
- A production-grade entailment verification agent. Pass a retrieved source chunk and an
16
- LLM-generated claim; get back a mathematically bounded entailment score, a verdict,
17
- and a BLAKE3 cryptographic attestation sealed into an append-only WORM audit chain β€”
18
- then passed through the ERE five-gate protocol before it leaves the system.
19
-
20
- ---
21
-
22
- ## What This Is
23
-
24
- LLMs hallucinate. RAG systems retrieve chunks and generate claims against them. Without
25
- a verification layer, a model can produce a plausible-sounding claim that contradicts
26
- its own source β€” and no downstream system will catch it.
27
-
28
- This agent is the verification layer. It does one thing:
29
-
30
- > **Given a retrieved source and a generated claim, determine with
31
- > cryptographic certainty whether the claim is entailed by the source.**
32
-
33
- It is not a chatbot. It is not a general-purpose NLI system. It is a production daemon
34
- that runs at the end of every RAG pipeline and refuses to propagate a claim until it
35
- can prove the claim is entailed.
36
-
37
- ---
38
-
39
- ## How This Compares to Google BERT
40
-
41
- | Property | Google BERT (2018) | This Agent |
42
- |----------|-------------------|------------|
43
- | Architecture | Bi-directional encoder | Cross-encoder (premise ++ hypothesis) |
44
- | NLI task | Fine-tuned on MNLI only | ANLI + TrueTeacher + MNLI (3-source) |
45
- | Hallucination detection | Not designed for it | Primary objective |
46
- | Negation detection | Weak (symmetric embeddings) | Strong (joint self-attention) |
47
- | Date/number flip detection | Fails | Catches (e.g. 1962 β†’ 1926) |
48
- | Runtime | Python / TF / PyTorch | Rust daemon, TensorRT FP16, GPU |
49
- | Latency | ~100-300 ms (Python) | <5 ms batched (TRT) |
50
- | Throughput | Single request | Dual-trigger continuous batching |
51
- | Audit trail | None | BLAKE3 + WORM chain per inference |
52
- | Security gates | None | ERE P1-P5 (5-gate sovereign protocol) |
53
- | Formal invariants | None | Lean 4, zero sorry |
54
- | License | Apache 2.0 | Tri-license (AGPL / BSL 1.1 / MIT) |
55
-
56
- **Key difference:** BERT embeds premise and hypothesis *separately* and compares them
57
- with cosine similarity. A cross-encoder concatenates them and runs joint self-attention.
58
- That joint attention is what lets this agent catch subtle hallucinations β€” the model
59
- can directly compare "born in 1962" against "born in 1926" at the token level.
60
- BERT cannot do this. It sees two vectors, not two sentences in dialogue.
61
-
62
- ---
63
-
64
- ## Why Cross-Encoder, Not Bi-Encoder
65
-
66
- A Bi-Encoder embeds premise and hypothesis separately. At inference, you compare
67
- embeddings with cosine similarity. This works for semantic similarity, but it misses:
68
-
69
- - Flipped dates: `"born in 1962"` vs `"born in 1926"` β€” both embed nearly identically
70
- - Switched subjects: `"X defeated Y"` vs `"Y defeated X"` β€” same semantic field
71
- - Negation: `"the vote passed"` vs `"the vote did not pass"`
72
-
73
- A Cross-Encoder concatenates both and runs them through a single forward pass:
74
-
75
- ```
76
- [CLS] retrieved_chunk [SEP] generated_claim [SEP]
77
- ```
78
-
79
- Self-attention directly compares entities across the premise-hypothesis boundary at
80
- every layer. The model learns to detect *contradiction*, not just *similarity*.
81
- This is the architecture that makes hallucination detection tractable.
82
-
83
- ---
84
-
85
- ## Architecture
86
-
87
- ```
88
- Training Pipeline (Python)
89
- β”‚
90
- DeBERTa-v3-base + 3-label head
91
- Weighted CrossEntropyLoss
92
- (Contradiction=2.0, Neutral=1.5, Entailment=1.0)
93
- ANLI + TrueTeacher + MNLI
94
- β”‚
95
- β–Ό
96
- ONNX export (dynamic axes)
97
- β”‚
98
- ORT graph optimization + FP16
99
- β”‚
100
- β–Ό
101
- TensorRT engine (.plan cache)
102
- β”‚
103
- Rust Inference Daemon
104
- β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€οΏ½οΏ½οΏ½β”
105
- β”‚ Dual-trigger batching β”‚
106
- β”‚ MAX_BATCH or 5 ms timer β”‚
107
- β”‚ Dynamic padding/ndarray β”‚
108
- β”‚ TRT forward pass (GPU) β”‚
109
- β”‚ Softmax β†’ score β”‚
110
- β”‚ BLAKE3 attestation seal β”‚
111
- β”‚ WORM ledger append β”‚
112
- β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
113
- β”‚
114
- HTTP POST /verify
115
- { score, verdict, hash }
116
- β”‚
117
- β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”
118
- β”‚ ERE P1-P5 β”‚ ← agent/ere_gate.py
119
- β”‚ Five gates β”‚
120
- β”‚ P5 seal added β”‚
121
- β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
122
- β”‚
123
- Gated response
124
- { score, verdict, hash,
125
- ere_seal, ere_gates }
126
- OR { ere_halt: true }
127
- ```
128
-
129
- ---
130
-
131
- ## Milestones
132
-
133
- | # | Milestone | Status |
134
- |---|-----------|--------|
135
- | M1 | DeBERTa-v3 cross-encoder + weighted 3-label loss | βœ… Done |
136
- | M2 | ANLI + TrueTeacher + MNLI joint training dataset | βœ… Done |
137
- | M3 | ONNX export + ORT FP16 graph optimization | βœ… Done |
138
- | M4 | TensorRT engine with .plan caching | βœ… Done |
139
- | M5 | Rust inference daemon (Tokio, Axum, dual-trigger batching) | βœ… Done |
140
- | M6 | BLAKE3 attestation seal per inference | βœ… Done |
141
- | M7 | WORM append-only audit chain (tamper-evident) | βœ… Done |
142
- | M8 | FPR=0.0 PR-curve threshold calibration | βœ… Done |
143
- | M9 | 11/11 tests passing (dataset, calibrate, ledger) | βœ… Done |
144
- | M10 | Lean 4 formal invariants (zero sorry) | βœ… Done |
145
- | M11 | ERE P1-P5 gate integration (`agent/ere_gate.py`) | βœ… Done |
146
- | M12 | Tri-license (AGPL / BSL 1.1 / MIT) | βœ… Done |
147
- | M13 | Sovereign Engine v2 gap integration (Gap 4 candidate) | πŸ”œ Planned |
148
- | M14 | Rust daemon ERE gate enforcement (inline, pre-response) | πŸ”œ Planned |
149
- | M15 | Benchmark vs NLI baselines (BERT, RoBERTa, DeBERTa-v2) | πŸ”œ Planned |
150
-
151
- ---
152
-
153
- ## ERE Gate Protocol
154
-
155
- Every verdict produced by this agent passes through the **ERE (Expected Reasoning Error)**
156
- five-gate protocol before leaving the system:
157
-
158
- | Gate | Check | Failure means |
159
- |------|-------|---------------|
160
- | P1 | No secrets in payload | Credential leaked in model output |
161
- | P2 | No eval / code injection | Adversarial input tried to inject code |
162
- | P3 | Loop safety | Output contains infinite loop without exit |
163
- | P4 | No telemetry beacons | Analytics SDK call in model output |
164
- | P5 | SHA-256 audit seal | Commitment over `agent_id:intent:verdict` |
165
-
166
- A verdict that fails any gate is suppressed. The caller receives `{ ere_halt: true }`.
167
- The WORM ledger records the halt. The chain is not broken.
168
-
169
- ```python
170
- from agent.ere_gate import gate_verdict
171
-
172
- raw = {"score": 0.98, "verdict": "Entailment", "hash": "a3f8..."}
173
- gated = gate_verdict(
174
- premise="The Battle of Hastings took place in 1066.",
175
- hypothesis="Hastings occurred in 1066.",
176
- raw_verdict=raw,
177
- )
178
-
179
- if not gated.allowed:
180
- raise RuntimeError(f"ERE halt: {gated.violations}")
181
-
182
- print(gated.to_dict())
183
- # { score, verdict, hash, ere_seal, ere_gates: {P1:T, P2:T, P3:T, P4:T, P5:T} }
184
- ```
185
-
186
- ---
187
-
188
- ## Full Pipeline
189
-
190
- ### 1. Install dependencies
191
-
192
- ```bash
193
- pip install -r requirements.txt
194
- ```
195
-
196
- ### 2. Download datasets
197
-
198
- ```
199
- data/
200
- anli/R1/{train,dev,test}.jsonl
201
- anli/R2/{train,dev,test}.jsonl
202
- anli/R3/{train,dev,test}.jsonl
203
- trueteacher/{train,dev}.jsonl # Google, 1.4M records
204
- mnli/{train,dev}.jsonl
205
- ```
206
-
207
- ### 3. Fine-tune DeBERTa-v3
208
-
209
- ```bash
210
- python -m bert.train \
211
- --data_dir data/ \
212
- --output_dir checkpoints/ \
213
- --backbone microsoft/deberta-v3-base \
214
- --epochs 5 \
215
- --batch_size 32 \
216
- --lr 2e-5
217
- ```
218
-
219
- ### 4. Export to ONNX + optimize FP16
220
-
221
- ```bash
222
- python -m bert.export \
223
- --checkpoint checkpoints/best_model.pt \
224
- --output_dir onnx/ \
225
- --device cuda
226
- ```
227
-
228
- ### 5. Calibrate rejection threshold
229
-
230
- ```bash
231
- python -m bert.calibrate \
232
- --checkpoint checkpoints/best_model.pt \
233
- --data_dir data/ \
234
- --output config/threshold.json
235
- ```
236
-
237
- ### 6. Build and run the Rust daemon
238
-
239
- ```bash
240
- cd daemon
241
- cargo build --release
242
- RUST_LOG=info ./target/release/bert-daemon --config ../config/daemon.json
243
- ```
244
-
245
- First startup: ~5 min for TensorRT engine compilation. Subsequent starts: instant from `.plan` cache.
246
-
247
- ### 7. Verify a claim
248
-
249
- ```bash
250
- curl -X POST http://localhost:8080/verify \
251
- -H "Content-Type: application/json" \
252
- -d '{
253
- "premise": "The Battle of Hastings took place in 1066.",
254
- "hypothesis": "Hastings occurred in 1066.",
255
- "chunk_id": "chunk-001"
256
- }'
257
- ```
258
-
259
- Response:
260
-
261
- ```json
262
- {
263
- "score": 0.9812,
264
- "verdict": "Entailment",
265
- "hash": "a3f8d2c1...",
266
- "ere_seal": "7f3c8a19...",
267
- "ere_gates": { "P1": true, "P2": true, "P3": true, "P4": true, "P5": true }
268
- }
269
- ```
270
-
271
- The `hash` is the BLAKE3 attestation over the inference. The `ere_seal` is the P5 SHA-256
272
- commitment over `agent_id:intent:verdict`. Both are recorded in the WORM ledger.
273
-
274
- ---
275
-
276
- ## File Structure
277
-
278
- ```
279
- bert-agent/
280
- β”œβ”€β”€ agent/
281
- β”‚ β”œβ”€β”€ __init__.py # Exports BERTEREGate, GatedVerdict, gate_verdict
282
- β”‚ └── ere_gate.py # ERE P1-P5 gate adapter for BERT verdicts
283
- β”œβ”€β”€ bert/
284
- β”‚ β”œβ”€β”€ dataset.py # ANLI + TrueTeacher + MNLI cross-encoder dataset
285
- β”‚ β”œβ”€β”€ model.py # DeBERTa-v3 cross-encoder + weighted loss
286
- β”‚ β”œβ”€β”€ train.py # Fine-tuning loop (AdamW + cosine LR)
287
- β”‚ β”œβ”€β”€ export.py # ONNX export + ORT FP16 graph optimization
288
- β”‚ β”œβ”€β”€ trt_session.py # TensorRT ORT session with optimization profiles
289
- β”‚ └── calibrate.py # PR curve threshold calibration
290
- β”œβ”€β”€ daemon/
291
- β”‚ β”œβ”€β”€ Cargo.toml
292
- β”‚ └── src/
293
- β”‚ β”œβ”€β”€ main.rs # Startup, channel wiring
294
- β”‚ β”œβ”€β”€ types.rs # VerifyRequest, Attestation, Config
295
- β”‚ β”œβ”€β”€ session.rs # TRT ORT session init
296
- β”‚ β”œβ”€β”€ inference.rs # Dual-trigger continuous batching loop
297
- β”‚ β”œβ”€β”€ ledger.rs # WORM append-only audit chain
298
- β”‚ └── server.rs # Axum HTTP /verify handler
299
- β”œβ”€β”€ config/
300
- β”‚ └── daemon.json
301
- β”œβ”€β”€ tests/
302
- β”‚ β”œβ”€β”€ test_dataset.py
303
- β”‚ β”œβ”€β”€ test_calibrate.py
304
- β”‚ └── test_ledger.py
305
- β”œβ”€β”€ Invariants.lean # Lean 4 formal invariants, zero sorry
306
- β”œβ”€β”€ LICENSE # Tri-license: AGPL-3.0 | BSL 1.1 | MIT
307
- └── requirements.txt
308
- ```
309
-
310
- ---
311
-
312
- ## Design Decisions
313
-
314
- | Decision | Why |
315
- |----------|-----|
316
- | DeBERTa-v3 over BERT/RoBERTa | Disentangled attention handles positional reasoning β€” critical for detecting reordered events |
317
- | Cross-Encoder over Bi-Encoder | Cannot cache embeddings, but self-attention compares entities across premise-hypothesis directly |
318
- | Weighted loss (2.0/1.5/1.0) | False-positive Entailment is the worst failure mode β€” weight Contradiction higher |
319
- | ANLI + TrueTeacher | Standard NLI is too easy; TrueTeacher mirrors actual LLM hallucination patterns |
320
- | FPR=0.0 threshold calibration | In a verification engine, precision > recall β€” never cite a hallucinated claim |
321
- | Dual-trigger batching (batch size OR 5ms) | Bounded latency guarantee without sacrificing GPU throughput |
322
- | Dynamic padding per batch | Pad to longest sequence in the batch, not global max β€” avoids wasted compute |
323
- | BLAKE3 + bincode attestation | Memory-bandwidth hashing speed; deterministic binary serialization (no JSON ordering ambiguity) |
324
- | WORM ledger as chain | Every record links to previous hash β€” tamper detection is immediate |
325
- | ERE P1-P5 gate layer | Every verdict inspected for secrets, injection, loops, telemetry before propagation |
326
- | Lean 4 invariants | Formal proof that well-formed agents satisfy trust and entropy bounds β€” not just assertions |
327
-
328
- ---
329
-
330
- ## Theoretical Foundation
331
-
332
- This agent is a component of the **Sovereign Stack**. Its cryptographic and formal
333
- foundations are documented in the following published papers:
334
-
335
- | DOI | Contribution |
336
- |-----|-------------|
337
- | [10.5281/zenodo.21443609](https://doi.org/10.5281/zenodo.21443609) | Jordan Spectral Transformer β€” phi-weighted routing |
338
- | [10.5281/zenodo.21132094](https://doi.org/10.5281/zenodo.21132094) | Sovereign Compute Architecture |
339
- | [10.5281/zenodo.20678420](https://doi.org/10.5281/zenodo.20678420) | Attention Exhaustion Attacks β€” 0% detection rate |
340
- | [10.5281/zenodo.21268911](https://doi.org/10.5281/zenodo.21268911) | GKN I4 Quartic Invariant and E7 Symmetry |
341
-
342
- Unified paper: [The Sovereign Stack](https://snapkittywest.github.io/hyperkitty/papers/sovereign-stack-unified.pdf)
343
-
344
- ---
345
-
346
- ## License
347
-
348
- Tri-license β€” choose any one:
349
-
350
- - **AGPL-3.0** for open source / community use
351
- - **BSL 1.1 β†’ MIT** for commercial / production use (< 5 servers free; converts to MIT 2029-01-01)
352
- - **MIT** after 2029-01-01
353
-
354
- See [LICENSE](LICENSE) for the full text and list of six protected inventions.
355
-
356
- Copyright (C) 2026 Ahmad Ali Parr, Jessica L. Williams / SNAPKITTYWEST
357
- Bel Esprit D'Accord Irrevocable Trust
358
-
359
- ---
360
-
361
- *Built to catch what BERT cannot see.*
362
- *Every claim sealed. Every halt recorded. Nothing propagates without proof.*
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: other
3
+ license_name: snapkitty-tri-license
4
+ license_link: https://huggingface.co/Snapkitty/bert-agent/blob/main/LICENSE
5
+ tags:
6
+ - snapkitty
7
+ ---
8
+
9
+ > Source: [github.com/SNAPKITTYWEST/bert-agent](https://github.com/SNAPKITTYWEST/bert-agent)
10
+
11
+ # BERT Cross-Encoder Entailment Agent
12
+
13
+ [![Tests](https://img.shields.io/badge/tests-11%2F11%20passing-brightgreen)](tests/)
14
+ [![License: Tri](https://img.shields.io/badge/license-AGPL%20%7C%20BSL%201.1%20%7C%20MIT-blue)](LICENSE)
15
+ [![Model: DeBERTa-v3](https://img.shields.io/badge/model-DeBERTa--v3--base-orange)](https://huggingface.co/microsoft/deberta-v3-base)
16
+ [![Backend: TensorRT](https://img.shields.io/badge/backend-TensorRT%20FP16-76b900)](https://developer.nvidia.com/tensorrt)
17
+ [![Rust](https://img.shields.io/badge/daemon-Rust%20%2F%20Tokio-orange)](daemon/)
18
+ [![Audit: BLAKE3+ERE](https://img.shields.io/badge/audit-BLAKE3%20%2B%20ERE%20P5-blueviolet)](agent/ere_gate.py)
19
+ [![WORM](https://img.shields.io/badge/ledger-WORM%20chain-critical)](daemon/src/ledger.rs)
20
+ [![Lean 4](https://img.shields.io/badge/invariants-Lean%204%20proved-informational)](Invariants.lean)
21
+
22
+ **Authors:** Ahmad Ali Parr, Jessica L. Williams (SNAPKITTYWEST)
23
+ **Stack:** DeBERTa-v3 Β· ONNX Β· TensorRT FP16 Β· Rust/Tokio Β· BLAKE3 Β· WORM ledger Β· ERE P1-P5
24
+
25
+ A production-grade entailment verification agent. Pass a retrieved source chunk and an
26
+ LLM-generated claim; get back a mathematically bounded entailment score, a verdict,
27
+ and a BLAKE3 cryptographic attestation sealed into an append-only WORM audit chain β€”
28
+ then passed through the ERE five-gate protocol before it leaves the system.
29
+
30
+ ---
31
+
32
+ ## What This Is
33
+
34
+ LLMs hallucinate. RAG systems retrieve chunks and generate claims against them. Without
35
+ a verification layer, a model can produce a plausible-sounding claim that contradicts
36
+ its own source β€” and no downstream system will catch it.
37
+
38
+ This agent is the verification layer. It does one thing:
39
+
40
+ > **Given a retrieved source and a generated claim, determine with
41
+ > cryptographic certainty whether the claim is entailed by the source.**
42
+
43
+ It is not a chatbot. It is not a general-purpose NLI system. It is a production daemon
44
+ that runs at the end of every RAG pipeline and refuses to propagate a claim until it
45
+ can prove the claim is entailed.
46
+
47
+ ---
48
+
49
+ ## How This Compares to Google BERT
50
+
51
+ | Property | Google BERT (2018) | This Agent |
52
+ |----------|-------------------|------------|
53
+ | Architecture | Bi-directional encoder | Cross-encoder (premise ++ hypothesis) |
54
+ | NLI task | Fine-tuned on MNLI only | ANLI + TrueTeacher + MNLI (3-source) |
55
+ | Hallucination detection | Not designed for it | Primary objective |
56
+ | Negation detection | Weak (symmetric embeddings) | Strong (joint self-attention) |
57
+ | Date/number flip detection | Fails | Catches (e.g. 1962 β†’ 1926) |
58
+ | Runtime | Python / TF / PyTorch | Rust daemon, TensorRT FP16, GPU |
59
+ | Latency | ~100-300 ms (Python) | <5 ms batched (TRT) |
60
+ | Throughput | Single request | Dual-trigger continuous batching |
61
+ | Audit trail | None | BLAKE3 + WORM chain per inference |
62
+ | Security gates | None | ERE P1-P5 (5-gate sovereign protocol) |
63
+ | Formal invariants | None | Lean 4, zero sorry |
64
+ | License | Apache 2.0 | Tri-license (AGPL / BSL 1.1 / MIT) |
65
+
66
+ **Key difference:** BERT embeds premise and hypothesis *separately* and compares them
67
+ with cosine similarity. A cross-encoder concatenates them and runs joint self-attention.
68
+ That joint attention is what lets this agent catch subtle hallucinations β€” the model
69
+ can directly compare "born in 1962" against "born in 1926" at the token level.
70
+ BERT cannot do this. It sees two vectors, not two sentences in dialogue.
71
+
72
+ ---
73
+
74
+ ## Why Cross-Encoder, Not Bi-Encoder
75
+
76
+ A Bi-Encoder embeds premise and hypothesis separately. At inference, you compare
77
+ embeddings with cosine similarity. This works for semantic similarity, but it misses:
78
+
79
+ - Flipped dates: `"born in 1962"` vs `"born in 1926"` β€” both embed nearly identically
80
+ - Switched subjects: `"X defeated Y"` vs `"Y defeated X"` β€” same semantic field
81
+ - Negation: `"the vote passed"` vs `"the vote did not pass"`
82
+
83
+ A Cross-Encoder concatenates both and runs them through a single forward pass:
84
+
85
+ ```
86
+ [CLS] retrieved_chunk [SEP] generated_claim [SEP]
87
+ ```
88
+
89
+ Self-attention directly compares entities across the premise-hypothesis boundary at
90
+ every layer. The model learns to detect *contradiction*, not just *similarity*.
91
+ This is the architecture that makes hallucination detection tractable.
92
+
93
+ ---
94
+
95
+ ## Architecture
96
+
97
+ ```
98
+ Training Pipeline (Python)
99
+ β”‚
100
+ DeBERTa-v3-base + 3-label head
101
+ Weighted CrossEntropyLoss
102
+ (Contradiction=2.0, Neutral=1.5, Entailment=1.0)
103
+ ANLI + TrueTeacher + MNLI
104
+ β”‚
105
+ β–Ό
106
+ ONNX export (dynamic axes)
107
+ β”‚
108
+ ORT graph optimization + FP16
109
+ β”‚
110
+ β–Ό
111
+ TensorRT engine (.plan cache)
112
+ β”‚
113
+ Rust Inference Daemon
114
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
115
+ β”‚ Dual-trigger batching β”‚
116
+ β”‚ MAX_BATCH or 5 ms timer β”‚
117
+ β”‚ Dynamic padding/ndarray β”‚
118
+ β”‚ TRT forward pass (GPU) β”‚
119
+ β”‚ Softmax β†’ score β”‚
120
+ β”‚ BLAKE3 attestation seal β”‚
121
+ β”‚ WORM ledger append β”‚
122
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
123
+ β”‚
124
+ HTTP POST /verify
125
+ { score, verdict, hash }
126
+ β”‚
127
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”
128
+ β”‚ ERE P1-P5 β”‚ ← agent/ere_gate.py
129
+ β”‚ Five gates β”‚
130
+ β”‚ P5 seal added β”‚
131
+ β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
132
+ β”‚
133
+ Gated response
134
+ { score, verdict, hash,
135
+ ere_seal, ere_gates }
136
+ OR { ere_halt: true }
137
+ ```
138
+
139
+ ---
140
+
141
+ ## Milestones
142
+
143
+ | # | Milestone | Status |
144
+ |---|-----------|--------|
145
+ | M1 | DeBERTa-v3 cross-encoder + weighted 3-label loss | βœ… Done |
146
+ | M2 | ANLI + TrueTeacher + MNLI joint training dataset | βœ… Done |
147
+ | M3 | ONNX export + ORT FP16 graph optimization | βœ… Done |
148
+ | M4 | TensorRT engine with .plan caching | βœ… Done |
149
+ | M5 | Rust inference daemon (Tokio, Axum, dual-trigger batching) | βœ… Done |
150
+ | M6 | BLAKE3 attestation seal per inference | βœ… Done |
151
+ | M7 | WORM append-only audit chain (tamper-evident) | βœ… Done |
152
+ | M8 | FPR=0.0 PR-curve threshold calibration | βœ… Done |
153
+ | M9 | 11/11 tests passing (dataset, calibrate, ledger) | βœ… Done |
154
+ | M10 | Lean 4 formal invariants (zero sorry) | βœ… Done |
155
+ | M11 | ERE P1-P5 gate integration (`agent/ere_gate.py`) | βœ… Done |
156
+ | M12 | Tri-license (AGPL / BSL 1.1 / MIT) | βœ… Done |
157
+ | M13 | Sovereign Engine v2 gap integration (Gap 4 candidate) | πŸ”œ Planned |
158
+ | M14 | Rust daemon ERE gate enforcement (inline, pre-response) | πŸ”œ Planned |
159
+ | M15 | Benchmark vs NLI baselines (BERT, RoBERTa, DeBERTa-v2) | πŸ”œ Planned |
160
+
161
+ ---
162
+
163
+ ## ERE Gate Protocol
164
+
165
+ Every verdict produced by this agent passes through the **ERE (Expected Reasoning Error)**
166
+ five-gate protocol before leaving the system:
167
+
168
+ | Gate | Check | Failure means |
169
+ |------|-------|---------------|
170
+ | P1 | No secrets in payload | Credential leaked in model output |
171
+ | P2 | No eval / code injection | Adversarial input tried to inject code |
172
+ | P3 | Loop safety | Output contains infinite loop without exit |
173
+ | P4 | No telemetry beacons | Analytics SDK call in model output |
174
+ | P5 | SHA-256 audit seal | Commitment over `agent_id:intent:verdict` |
175
+
176
+ A verdict that fails any gate is suppressed. The caller receives `{ ere_halt: true }`.
177
+ The WORM ledger records the halt. The chain is not broken.
178
+
179
+ ```python
180
+ from agent.ere_gate import gate_verdict
181
+
182
+ raw = {"score": 0.98, "verdict": "Entailment", "hash": "a3f8..."}
183
+ gated = gate_verdict(
184
+ premise="The Battle of Hastings took place in 1066.",
185
+ hypothesis="Hastings occurred in 1066.",
186
+ raw_verdict=raw,
187
+ )
188
+
189
+ if not gated.allowed:
190
+ raise RuntimeError(f"ERE halt: {gated.violations}")
191
+
192
+ print(gated.to_dict())
193
+ # { score, verdict, hash, ere_seal, ere_gates: {P1:T, P2:T, P3:T, P4:T, P5:T} }
194
+ ```
195
+
196
+ ---
197
+
198
+ ## Full Pipeline
199
+
200
+ ### 1. Install dependencies
201
+
202
+ ```bash
203
+ pip install -r requirements.txt
204
+ ```
205
+
206
+ ### 2. Download datasets
207
+
208
+ ```
209
+ data/
210
+ anli/R1/{train,dev,test}.jsonl
211
+ anli/R2/{train,dev,test}.jsonl
212
+ anli/R3/{train,dev,test}.jsonl
213
+ trueteacher/{train,dev}.jsonl # Google, 1.4M records
214
+ mnli/{train,dev}.jsonl
215
+ ```
216
+
217
+ ### 3. Fine-tune DeBERTa-v3
218
+
219
+ ```bash
220
+ python -m bert.train \
221
+ --data_dir data/ \
222
+ --output_dir checkpoints/ \
223
+ --backbone microsoft/deberta-v3-base \
224
+ --epochs 5 \
225
+ --batch_size 32 \
226
+ --lr 2e-5
227
+ ```
228
+
229
+ ### 4. Export to ONNX + optimize FP16
230
+
231
+ ```bash
232
+ python -m bert.export \
233
+ --checkpoint checkpoints/best_model.pt \
234
+ --output_dir onnx/ \
235
+ --device cuda
236
+ ```
237
+
238
+ ### 5. Calibrate rejection threshold
239
+
240
+ ```bash
241
+ python -m bert.calibrate \
242
+ --checkpoint checkpoints/best_model.pt \
243
+ --data_dir data/ \
244
+ --output config/threshold.json
245
+ ```
246
+
247
+ ### 6. Build and run the Rust daemon
248
+
249
+ ```bash
250
+ cd daemon
251
+ cargo build --release
252
+ RUST_LOG=info ./target/release/bert-daemon --config ../config/daemon.json
253
+ ```
254
+
255
+ First startup: ~5 min for TensorRT engine compilation. Subsequent starts: instant from `.plan` cache.
256
+
257
+ ### 7. Verify a claim
258
+
259
+ ```bash
260
+ curl -X POST http://localhost:8080/verify \
261
+ -H "Content-Type: application/json" \
262
+ -d '{
263
+ "premise": "The Battle of Hastings took place in 1066.",
264
+ "hypothesis": "Hastings occurred in 1066.",
265
+ "chunk_id": "chunk-001"
266
+ }'
267
+ ```
268
+
269
+ Response:
270
+
271
+ ```json
272
+ {
273
+ "score": 0.9812,
274
+ "verdict": "Entailment",
275
+ "hash": "a3f8d2c1...",
276
+ "ere_seal": "7f3c8a19...",
277
+ "ere_gates": { "P1": true, "P2": true, "P3": true, "P4": true, "P5": true }
278
+ }
279
+ ```
280
+
281
+ The `hash` is the BLAKE3 attestation over the inference. The `ere_seal` is the P5 SHA-256
282
+ commitment over `agent_id:intent:verdict`. Both are recorded in the WORM ledger.
283
+
284
+ ---
285
+
286
+ ## File Structure
287
+
288
+ ```
289
+ bert-agent/
290
+ β”œβ”€β”€ agent/
291
+ β”‚ β”œβ”€β”€ __init__.py # Exports BERTEREGate, GatedVerdict, gate_verdict
292
+ β”‚ └── ere_gate.py # ERE P1-P5 gate adapter for BERT verdicts
293
+ β”œβ”€β”€ bert/
294
+ β”‚ β”œβ”€β”€ dataset.py # ANLI + TrueTeacher + MNLI cross-encoder dataset
295
+ β”‚ β”œβ”€β”€ model.py # DeBERTa-v3 cross-encoder + weighted loss
296
+ β”‚ β”œβ”€β”€ train.py # Fine-tuning loop (AdamW + cosine LR)
297
+ β”‚ β”œβ”€β”€ export.py # ONNX export + ORT FP16 graph optimization
298
+ β”‚ β”œβ”€β”€ trt_session.py # TensorRT ORT session with optimization profiles
299
+ β”‚ └── calibrate.py # PR curve threshold calibration
300
+ β”œβ”€β”€ daemon/
301
+ β”‚ β”œβ”€β”€ Cargo.toml
302
+ β”‚ └── src/
303
+ β”‚ β”œβ”€β”€ main.rs # Startup, channel wiring
304
+ β”‚ β”œβ”€β”€ types.rs # VerifyRequest, Attestation, Config
305
+ β”‚ β”œβ”€β”€ session.rs # TRT ORT session init
306
+ β”‚ β”œβ”€β”€ inference.rs # Dual-trigger continuous batching loop
307
+ β”‚ β”œβ”€β”€ ledger.rs # WORM append-only audit chain
308
+ β”‚ └── server.rs # Axum HTTP /verify handler
309
+ β”œβ”€β”€ config/
310
+ β”‚ └── daemon.json
311
+ β”œβ”€β”€ tests/
312
+ β”‚ β”œβ”€β”€ test_dataset.py
313
+ β”‚ β”œβ”€β”€ test_calibrate.py
314
+ β”‚ └── test_ledger.py
315
+ β”œβ”€β”€ Invariants.lean # Lean 4 formal invariants, zero sorry
316
+ β”œβ”€β”€ LICENSE # Tri-license: AGPL-3.0 | BSL 1.1 | MIT
317
+ └── requirements.txt
318
+ ```
319
+
320
+ ---
321
+
322
+ ## Design Decisions
323
+
324
+ | Decision | Why |
325
+ |----------|-----|
326
+ | DeBERTa-v3 over BERT/RoBERTa | Disentangled attention handles positional reasoning β€” critical for detecting reordered events |
327
+ | Cross-Encoder over Bi-Encoder | Cannot cache embeddings, but self-attention compares entities across premise-hypothesis directly |
328
+ | Weighted loss (2.0/1.5/1.0) | False-positive Entailment is the worst failure mode β€” weight Contradiction higher |
329
+ | ANLI + TrueTeacher | Standard NLI is too easy; TrueTeacher mirrors actual LLM hallucination patterns |
330
+ | FPR=0.0 threshold calibration | In a verification engine, precision > recall β€” never cite a hallucinated claim |
331
+ | Dual-trigger batching (batch size OR 5ms) | Bounded latency guarantee without sacrificing GPU throughput |
332
+ | Dynamic padding per batch | Pad to longest sequence in the batch, not global max β€” avoids wasted compute |
333
+ | BLAKE3 + bincode attestation | Memory-bandwidth hashing speed; deterministic binary serialization (no JSON ordering ambiguity) |
334
+ | WORM ledger as chain | Every record links to previous hash β€” tamper detection is immediate |
335
+ | ERE P1-P5 gate layer | Every verdict inspected for secrets, injection, loops, telemetry before propagation |
336
+ | Lean 4 invariants | Formal proof that well-formed agents satisfy trust and entropy bounds β€” not just assertions |
337
+
338
+ ---
339
+
340
+ ## Theoretical Foundation
341
+
342
+ This agent is a component of the **Sovereign Stack**. Its cryptographic and formal
343
+ foundations are documented in the following published papers:
344
+
345
+ | DOI | Contribution |
346
+ |-----|-------------|
347
+ | [10.5281/zenodo.21443609](https://doi.org/10.5281/zenodo.21443609) | Jordan Spectral Transformer β€” phi-weighted routing |
348
+ | [10.5281/zenodo.21132094](https://doi.org/10.5281/zenodo.21132094) | Sovereign Compute Architecture |
349
+ | [10.5281/zenodo.20678420](https://doi.org/10.5281/zenodo.20678420) | Attention Exhaustion Attacks β€” 0% detection rate |
350
+ | [10.5281/zenodo.21268911](https://doi.org/10.5281/zenodo.21268911) | GKN I4 Quartic Invariant and E7 Symmetry |
351
+
352
+ Unified paper: [The Sovereign Stack](https://snapkittywest.github.io/hyperkitty/papers/sovereign-stack-unified.pdf)
353
+
354
+ ---
355
+
356
+ ## License
357
+
358
+ Tri-license β€” choose any one:
359
+
360
+ - **AGPL-3.0** for open source / community use
361
+ - **BSL 1.1 β†’ MIT** for commercial / production use (< 5 servers free; converts to MIT 2029-01-01)
362
+ - **MIT** after 2029-01-01
363
+
364
+ See [LICENSE](LICENSE) for the full text and list of six protected inventions.
365
+
366
+ Copyright (C) 2026 Ahmad Ali Parr, Jessica L. Williams / SNAPKITTYWEST
367
+ Bel Esprit D'Accord Irrevocable Trust
368
+
369
+ ---
370
+
371
+ *Built to catch what BERT cannot see.*
372
+ *Every claim sealed. Every halt recorded. Nothing propagates without proof.*
373
+
374
+ ### πŸ’Ό Commercial License
375
+
376
+ Snapkitty code is free and open under **AGPL-3.0** for open-source use. Building a commercial product or service? A **proprietary commercial license** from Snapkitty Collective LLC lets you ship this code without the AGPL's source-sharing and network-use obligations.
377
+
378
+ **[β†’ Get a commercial license](mailto:A.parr@belespritdaccord.uk?subject=Commercial%20license:%20bert-agent)** Β· A.parr@belespritdaccord.uk