spencernorton commited on
Commit
5be8f06
·
verified ·
1 Parent(s): 9af29a6

Add canonical chart pipeline, CHARTS_MANIFEST.json, and synchronized dark-mode benchmark charts

Browse files
README.md CHANGED
@@ -67,7 +67,7 @@ print(pred["heads"].keys()) # dict_keys(['category', 'adult', 'junk', 'anime
67
  Armiger and Armiger Ultra ship with turnkey HTTP services, Docker Compose stacks, and reference adapters in [`examples/`](examples) and [`docs/INTEGRATION_GUIDE.md`](docs/INTEGRATION_GUIDE.md):
68
 
69
  - **[`DH-Waypoint` Integration (`examples/dh-waypoint/`)](examples/dh-waypoint)** — Drop-in `processorapi/v1` service (`armiger_waypoint_processor.py`) and plugin manifest (`07-armiger-ultra.plugin.yml`) implementing batch classification (`dh-waypoint.processor.v1`), pre-ingest cohort admission (`dh-waypoint.processors.admission.v1`), and 4-tier `dh-waypoint.processors.feedback.v1` closed-loop telemetry for [`spencernorton/DH-Waypoint`](https://github.com/spencernorton/DH-Waypoint).
70
- - **[`Bitmagnet` Integration (`examples/bitmagnet/`)](examples/bitmagnet)** — Pre-ingest / post-crawl batch classifier and malware/honeypot pruner (`bitmagnet_armiger_bridge.py`) that upgrades upstream Bitmagnet from `35.29%` rule accuracy to **`95.49%` 11-class neural accuracy** and automatically prunes disguised `.mkv.exe`/`.scr`/`.lnk` malware traps via GraphQL `torrent.delete`.
71
  - **[`*Arr` Stack & `qBittorrent` Integration (`examples/arr-stack/`)](examples/arr-stack)** — Pre-grab Torznab XML filtering proxy (`armiger_torznab_proxy.py`) between `Prowlarr` / `Bitmagnet` / `DH-Waypoint` and `Sonarr`, `Radarr`, `Lidarr`, `Readarr`, and `Whisparr`, paired with a post-import webhook & `ffprobe` ground-truth receiver (`armiger_arr_webhook_receiver.py`) wired into `SeriesWebhookAdapter`, `MovieWebhookAdapter`, `AudioWebhookAdapter`, `PublicationWebhookAdapter`, `QBittorrentAdapter`, and `PhysicalGroundTruthVerifier`.
72
 
73
  See the **[Complete Ecosystem Integration Guide (`docs/INTEGRATION_GUIDE.md`)](docs/INTEGRATION_GUIDE.md)** for architecture diagrams, Docker Compose files, and step-by-step setup instructions.
@@ -79,7 +79,7 @@ See the **[Complete Ecosystem Integration Guide (`docs/INTEGRATION_GUIDE.md`)](d
79
  All metrics below are reproducibly computed using `armiger_inference.py` against the **original, unmutated ground-truth evaluation keys** (`rows.y`), separating **Standalone Neural ONNX (`armiger.onnx`)** from **Fair Blind Hybrid (`+ ZeroCueCatalogPlugin` & `AudioLanguageGuard`)**:
80
 
81
  1. **`category` (11 classes):** `movie`, `tv_show`, `xxx`, `music`, `comic`, `game`, `audiobook`, `software`, `ebook`, `course`, `unknown`
82
- - **`oct15_confirmation` (`N=2,835`):** **`95.06%`** Standalone Neural INT8 (**`95.49%`** Fair Blind Hybrid; **`96.60%`** Neural / **`97.15%`** Hybrid on Video Movie-vs-TV `N=1,296`; **`96.17%`** Neural / **`96.34%`** Hybrid on 4-Medium `N=1,748`)
83
  - **`fresh_confirmation` (`N=1,402`):** **`94.44%`** Standalone Neural INT8 (**`94.51%`** FP32 / **`94.58%`** Fair Blind Hybrid)
84
  - **`beyond_confirmation` (`N=1,025`):** **`92.88%`** Standalone Neural (**`95.12%`** Fair Blind Hybrid, `+2.24 pp`)
85
  - **`tc_truespec_2000` (`N=2,000` specialist zero-cue anime/video):** **`87.35%`** Standalone Neural INT8 (**`91.50%`** Fair Blind Hybrid, `+4.15 pp` from `BLAKE2b-64` catalog + structural rules)
@@ -127,37 +127,37 @@ All metrics below are reproducibly computed using `armiger_inference.py` against
127
 
128
  ![Armiger vs Open-Source Torrent Classifiers Across 7 Core Dimensions](assets/armiger_vs_torrent_classifiers_6dims.png)
129
 
130
- | System / Model | Footprint | 11-Class Category (`oct15` `N=2,835`) | Movie vs. TV (`N=1,296`) | Catalog Matching (`N=1,296`) | Audio Language (`N=545`) | Anime & Dub (`N=507`) | Adult / NSFW Gate (`N=2,781`) | Junk / Malware (`N=2,170`) | Swarm Liveliness (AUROC) |
131
  | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
132
- | **[Armiger Ultra (Fair Hybrid)](https://huggingface.co/NorviTech/armiger-ultra)** | `32.3 MB` (`+26 MB` cat.) | **`95.49%`** (`98.47%` mlang) | **`97.15%`** | **`96.39%`** | **`97.80%`** | **`99.61%`** | **`98.53%`** | **`100.00%`** (`99.90%` beyond) | **`96.83%`** Whse / **`92.42%`** Pub |
133
- | **Armiger (8.3 MB INT8 Neural)** | **`8.3 MB`** | **`95.06%`** (`97.37%` mlang) | **`96.60%`** | **`95.85%`** | **`96.88%`** | **`99.61%`** | **`98.53%`** | **`100.00%`** (`99.90%` beyond) | **`86.64%`** Priors (`92.42%` w/ Adapter) |
134
- | **MIMMO BERT (360M)** | `~1,400 MB` | `72.35%` | `56.92%` (`93.61%` 4-Med) | `60.03%` | N/A | N/A | `91.05%` | N/A | N/A |
135
- | **MIMMO Cascade** | `~1,400 MB` | `71.43%` | `57.00%` (`93.97%` 4-Med) | `60.11%` | N/A | N/A | `89.68%` | N/A | N/A |
136
- | **RTN (`rank-torrent-name`)** | Code Only | `53.77%` | `81.73%` | `80.56%` | `95.33%` | `77.65%` | `79.00%` | `50.38%` (`2.2%` rec.) | N/A |
137
- | **PTT / Parsett** | Code Only | `53.77%` | `81.73%` | `80.56%` | `95.33%` | `77.65%` | `79.00%` | N/A | N/A |
138
- | **GuessIt** | Code Only | `38.83%` | `84.68%` | `84.06%` | `96.01%` | `75.90%` | N/A | N/A | N/A |
139
- | **PTN (`parse-torrent-title`)** | Code Only | `35.72%` | `77.84%` | `77.60%` | `95.05%` | `68.65%` | N/A | N/A | N/A |
140
- | **Anitomy** | Code Only | `33.52%` | `73.09%` | `72.78%` | `94.23%` | `74.00%` | N/A | N/A | N/A |
141
- | **Bitmagnet Built-In** | Code Only | `35.29%` | `43.39%` (`88.4%` ans.) | `43.39%` | `95.26%` | N/A | `76.73%` | `54.60%` (`9.2%` rec.) | N/A |
142
 
143
  ### Per-Category Accuracy Breakdown Across All 10 Media & Software Categories (Unmutated Keys)
144
 
145
  ![Categorical Accuracy Breakdown Across All 10 Media & Software Categories](assets/armiger_categorical_breakdown.png)
146
 
147
- | Content Category | `oct15` (`N=2,835`) Armiger Ultra (Fair Hybrid) | `oct15` (`N=2,835`) Armiger (INT8 Neural) | `oct15` MIMMO BERT (360M) | `oct15` Bitmagnet Built-In | `beyond` (`N=1,025`) Armiger Ultra (Fair Hybrid) | `beyond` (`N=1,025`) Armiger (Neural) | `beyond` OpenAI GPT (`gpt-6-luna`)* | `beyond` Google Gemini (`gemini-3.8-flash-low`)* |
148
  | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
149
- | **Audiobook** | **`97.89%`** | **`97.89%`** | `0.00%` | `9.47%` | **`100.00%`** | **`100.00%`** | **`100.00%`** | `98.67%` |
150
- | **Adult / XXX** | **`97.80%`** | **`97.80%`** | `95.50%` | `39.46%` | `91.95%` | `91.95%` | `97.70%` | **`98.85%`** |
151
- | **TV Show** | **`97.50%`** | `97.00%` | `58.40%` | `28.62%` | `96.32%` | `86.03%` | **`99.26%`** | `95.59%` |
152
- | **Movie** | **`96.83%`** | `96.26%` | `78.85%` | `55.83%` | **`96.84%`** | `92.63%` | `95.79%` | `95.79%` |
153
- | **Software** | **`93.75%`** | **`93.75%`** | `59.38%` | `15.62%` | `94.59%` | `94.59%` | **`97.30%`** | `78.38%` |
154
  | **Music** | **`90.71%`** | **`90.71%`** | `77.86%` | `7.86%` | `83.33%` | `83.33%` | **`100.00%`** | **`100.00%`** |
155
- | **Game** | **`90.16%`** | `86.89%` | `0.00%` | `0.00%` | `96.30%` | `95.56%` | **`99.26%`** | **`99.26%`** |
156
- | **Ebook** | **`88.00%`** | **`88.00%`** | `80.00%` | `4.00%` | `98.40%` | `98.40%` | `96.80%` | **`99.20%`** |
157
- | **Course** | **`81.82%`** | `78.79%` | `0.00%` | `0.00%` | `92.00%` | `92.00%` | `96.00%` | **`99.00%`** |
158
- | **Comic** | **`66.67%`** | **`66.67%`** | `0.00%` | `0.00%` | **`98.33%`** | `95.00%` | **`99.17%`** | `95.83%` |
159
 
160
- *Note on `beyond_confirmation` (`N=1,025`): `gpt-6-luna` and `gemini-3.8-flash-low` were the two frontier teacher models used in the multi-teacher reference consensus for `beyond_confirmation`, giving them teacher-in-the-loop consensus affinity on that split. Independent blind `claude-haiku-4-5` (`N=240`) scored `93.75%` category accuracy and local `Vinci-MLE-8B` scored `80.77%`.*
161
 
162
  ---
163
 
@@ -171,14 +171,14 @@ All metrics below are reproducibly computed using `armiger_inference.py` against
171
 
172
  ![Cost Benchmark vs Frontier Cloud LLMs and Local GPU LLM](assets/armiger_vs_llms_cost_comparison.png)
173
 
174
- | Model | Overall 6-Dim Mean | 11-Class Category | Catalog Matching | Audio Language | Anime & Dub | Junk / Malware (Bal.) | Swarm Liveliness (AUROC) | Measured Hardware Speed | Cost per 1M Torrents (Batched / Real-Time) |
175
  | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
176
- | **[Armiger Ultra (Fair Hybrid)](https://huggingface.co/NorviTech/armiger-ultra)** | **`97.55%`** | `95.49%` (`oct15`) / `95.12%` (`beyond`) | **`96.39%`** | `97.80%` | `98.90%` (`99.61%` `oct15`) | `99.90%` (`100%` `oct15`) | **`96.83%`** | **`0.21 ms` RTX / `0.29 ms` M4 Pro MPS** | **`$0.00` API** (`$0.0040` compute) |
177
- | **Armiger (8.3 MB INT8 Neural)** | **`96.50%`** | `95.06%` (`oct15`) / `92.88%` (`beyond`) | `95.85%` | `96.88%` | `98.90%` (`99.61%` `oct15`) | `99.90%` (`100%` `oct15`) | `92.42%` (`86.64%` Priors) | **`2.44 ms` single / `3.07 ms` batch-64 (M4 Pro CPU)** | **`$0.00` API** (`$0.0020` compute) |
178
- | **Google Gemini (`gemini-3.8-flash-low`)\*** | `96.35%` | `97.13%`* | `94.05%`* | **`99.88%`**\* | `97.82%`* | **`100.00%`** | `89.20%` | `~450 ms` | `$94.90` / `$147.00` |
179
- | **Anthropic Claude (`claude-haiku-4-5`)** | `93.02%` | `93.75%` | `86.11%` | `95.68%` | **`99.44%`** | `93.37%` | `89.76%` | `~310 ms` | `$712.00` / `$1,220.00` |
180
- | **OpenAI GPT (`gpt-6-luna`)\*** | `87.85%` | **`98.02%`**\* | `91.77%`* | `99.65%`* | `97.82%`* | `50.00%` (`0%` rec.) | `89.82%` | `~365 ms` | `$127.30` / `$220.50` |
181
- | **Local GPU LLM (`Vinci-MLE-8B-1.0`)** | `85.71%` | `80.77%` | `77.88%` | `97.30%` | `93.79%` | `98.21%` | `66.32%` | `~185 ms` (`5.4/s` RTX 4070 TiS) | `$0.00` API (`$1.85` local power) |
182
 
183
  ---
184
 
 
67
  Armiger and Armiger Ultra ship with turnkey HTTP services, Docker Compose stacks, and reference adapters in [`examples/`](examples) and [`docs/INTEGRATION_GUIDE.md`](docs/INTEGRATION_GUIDE.md):
68
 
69
  - **[`DH-Waypoint` Integration (`examples/dh-waypoint/`)](examples/dh-waypoint)** — Drop-in `processorapi/v1` service (`armiger_waypoint_processor.py`) and plugin manifest (`07-armiger-ultra.plugin.yml`) implementing batch classification (`dh-waypoint.processor.v1`), pre-ingest cohort admission (`dh-waypoint.processors.admission.v1`), and 4-tier `dh-waypoint.processors.feedback.v1` closed-loop telemetry for [`spencernorton/DH-Waypoint`](https://github.com/spencernorton/DH-Waypoint).
70
+ - **[`Bitmagnet` Integration (`examples/bitmagnet/`)](examples/bitmagnet)** — Pre-ingest / post-crawl batch classifier and malware/honeypot pruner (`bitmagnet_armiger_bridge.py`) that upgrades upstream Bitmagnet from `35.17%` rule accuracy to **`95.49%` 11-class neural accuracy** and automatically prunes disguised `.mkv.exe`/`.scr`/`.lnk` malware traps via GraphQL `torrent.delete`.
71
  - **[`*Arr` Stack & `qBittorrent` Integration (`examples/arr-stack/`)](examples/arr-stack)** — Pre-grab Torznab XML filtering proxy (`armiger_torznab_proxy.py`) between `Prowlarr` / `Bitmagnet` / `DH-Waypoint` and `Sonarr`, `Radarr`, `Lidarr`, `Readarr`, and `Whisparr`, paired with a post-import webhook & `ffprobe` ground-truth receiver (`armiger_arr_webhook_receiver.py`) wired into `SeriesWebhookAdapter`, `MovieWebhookAdapter`, `AudioWebhookAdapter`, `PublicationWebhookAdapter`, `QBittorrentAdapter`, and `PhysicalGroundTruthVerifier`.
72
 
73
  See the **[Complete Ecosystem Integration Guide (`docs/INTEGRATION_GUIDE.md`)](docs/INTEGRATION_GUIDE.md)** for architecture diagrams, Docker Compose files, and step-by-step setup instructions.
 
79
  All metrics below are reproducibly computed using `armiger_inference.py` against the **original, unmutated ground-truth evaluation keys** (`rows.y`), separating **Standalone Neural ONNX (`armiger.onnx`)** from **Fair Blind Hybrid (`+ ZeroCueCatalogPlugin` & `AudioLanguageGuard`)**:
80
 
81
  1. **`category` (11 classes):** `movie`, `tv_show`, `xxx`, `music`, `comic`, `game`, `audiobook`, `software`, `ebook`, `course`, `unknown`
82
+ - **`oct15_confirmation` (`N=2,835`):** **`95.06%`** Standalone Neural INT8 (**`95.49%`** Fair Blind Hybrid; **`96.60%`** Neural / **`97.30%`** Hybrid on Video Movie-vs-TV `N=1,296`; **`96.17%`** Neural / **`96.34%`** Hybrid on 4-Medium `N=1,748`)
83
  - **`fresh_confirmation` (`N=1,402`):** **`94.44%`** Standalone Neural INT8 (**`94.51%`** FP32 / **`94.58%`** Fair Blind Hybrid)
84
  - **`beyond_confirmation` (`N=1,025`):** **`92.88%`** Standalone Neural (**`95.12%`** Fair Blind Hybrid, `+2.24 pp`)
85
  - **`tc_truespec_2000` (`N=2,000` specialist zero-cue anime/video):** **`87.35%`** Standalone Neural INT8 (**`91.50%`** Fair Blind Hybrid, `+4.15 pp` from `BLAKE2b-64` catalog + structural rules)
 
127
 
128
  ![Armiger vs Open-Source Torrent Classifiers Across 7 Core Dimensions](assets/armiger_vs_torrent_classifiers_6dims.png)
129
 
130
+ | System / Model | Footprint | 11-Class Category (`oct15` `N=2,835`) | Movie vs. TV (`N=1,296`) | Catalog Matching (`N=1,296`) | Audio Language (`N=545`) | Anime & Dub (`N=507` / `tc2000`) | Adult / NSFW Gate (`N=2,781`) | Junk / Malware (`N=2,170`) | Swarm Liveliness (AUROC) |
131
  | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
132
+ | **[Armiger Ultra (Fair Hybrid)](https://huggingface.co/NorviTech/armiger-ultra)** | `32.3 MB` (`+26 MB` cat.) | **`95.49%`** (`98.47%` mlang) | **`97.30%`** | **`96.53%`** | **`97.80%`** | **`99.61%`** (`95.80%` tc2000) | **`98.53%`** | **`100.00%`** (`99.90%` beyond) | **`96.83%`** Whse / **`92.42%`** Pub |
133
+ | **Armiger (8.3 MB INT8 + Plugins)** | **`8.3 MB`** | **`95.49%`** (`95.06%` Raw) | **`97.30%`** (`96.60%` Raw) | **`96.53%`** (`95.83%` Raw) | **`97.80%`** (`96.88%` Raw) | **`99.61%`** (`95.80%` tc2000) | **`98.49%`** | **`100.00%`** (`99.90%` beyond) | **`92.42%`** Pub (`86.64%` Priors) |
134
+ | **MIMMO BERT (360M)** | `~1,400 MB` | `72.24%` | `76.00%` (`93.61%` 4-Med) | `60.26%` | N/A | N/A | `91.05%` | N/A | N/A |
135
+ | **MIMMO Cascade** | `~1,400 MB` | `71.32%` | `76.08%` (`93.97%` 4-Med) | `60.34%` | N/A | N/A | `89.68%` | N/A | N/A |
136
+ | **RTN (`rank-torrent-name`)** | Code Only | `53.58%` | `81.64%` | `80.48%` | `93.76%` | `77.65%` | `79.00%` | `50.38%` (`0%` rec.) | N/A |
137
+ | **PTT / Parsett** | Code Only | `53.58%` | `81.64%` | `80.48%` | `93.76%` | `77.65%` | `79.00%` | N/A | N/A |
138
+ | **GuessIt** | Code Only | `38.69%` | `84.65%` | `84.03%` | `94.86%` | `78.80%` | N/A | N/A | N/A |
139
+ | **PTN (`parse-torrent-title`)** | Code Only | `35.59%` | `77.85%` | `77.62%` | `93.21%` | `68.65%` | N/A | N/A | N/A |
140
+ | **Anitomy** | Code Only | `33.40%` | `73.07%` | `72.76%` | `90.46%` | `64.55%` | N/A | N/A | N/A |
141
+ | **Bitmagnet Built-In** | Code Only | `35.17%` | `43.21%` (`88.4%` ans.) | `43.21%` | `88.26%` | N/A | `76.73%` | `54.60%` (`0%` rec.) | N/A |
142
 
143
  ### Per-Category Accuracy Breakdown Across All 10 Media & Software Categories (Unmutated Keys)
144
 
145
  ![Categorical Accuracy Breakdown Across All 10 Media & Software Categories](assets/armiger_categorical_breakdown.png)
146
 
147
+ | Content Category | `oct15` (`N=2,835`) Armiger Ultra (Fair Hybrid) | `oct15` (`N=2,835`) Armiger (INT8 + ZeroCue) | `oct15` MIMMO BERT (360M) | `oct15` Bitmagnet Built-In | `beyond` (`N=1,025`) Armiger Ultra (Fair Hybrid) | `beyond` (`N=1,025`) Armiger (INT8 + ZeroCue) | `beyond` OpenAI GPT (`gpt-6-luna` LOTO)* | `beyond` Google Gemini (`gemini-3.8-flash-low` LOTO)* |
148
  | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
149
+ | **Audiobook** | **`97.89%`** | **`97.89%`** | `0.00%` | `9.47%` | **`100.00%`** | **`100.00%`** | `98.67%` | `98.00%` |
150
+ | **Adult / XXX** | **`97.80%`** | **`97.80%`** | `95.50%` | `39.37%` | `91.95%` | `91.95%` | `94.83%` | **`95.69%`** |
151
+ | **TV Show** | **`97.50%`** | **`97.50%`** | `58.40%` | `28.62%` | `96.32%` | `96.32%` | **`97.79%`** | `93.75%` |
152
+ | **Movie** | **`97.12%`** | **`97.12%`** | `78.85%` | `55.83%` | **`96.84%`** | **`96.84%`** | `94.21%` | `92.63%` |
153
+ | **Software** | **`93.75%`** | **`93.75%`** | `59.38%` | `15.62%` | `94.59%` | `94.59%` | **`97.30%`** | `77.03%` |
154
  | **Music** | **`90.71%`** | **`90.71%`** | `77.86%` | `7.86%` | `83.33%` | `83.33%` | **`100.00%`** | **`100.00%`** |
155
+ | **Game** | **`90.16%`** | **`90.16%`** | `0.00%` | `0.00%` | `96.30%` | `96.30%` | **`98.52%`** | **`98.52%`** |
156
+ | **Ebook** | **`88.00%`** | **`88.00%`** | `80.00%` | `4.00%` | **`98.40%`** | **`98.40%`** | `96.00%` | `96.80%` |
157
+ | **Course** | **`81.82%`** | **`81.82%`** | `0.00%` | `0.00%` | `92.00%` | `92.00%` | `95.50%` | **`97.50%`** |
158
+ | **Comic** | **`66.67%`** | **`66.67%`** | `0.00%` | `0.00%` | **`98.33%`** | **`98.33%`** | `96.67%` | `95.00%` |
159
 
160
+ *Note on `beyond_confirmation` (`N=1,025`): `gpt-6-luna` and `gemini-3.8-flash-low` are evaluated using non-circular Leave-One-Teacher-Out (LOTO) reference keys (`self_vote_weight = 0.0`) so neither teacher model is scored against its own deciding majority vote (`95.12%` and `93.80%` LOTO vs. `96.59%` and `95.61%` circular self-voted).*
161
 
162
  ---
163
 
 
171
 
172
  ![Cost Benchmark vs Frontier Cloud LLMs and Local GPU LLM](assets/armiger_vs_llms_cost_comparison.png)
173
 
174
+ | Model | Overall 6-Dim Mean (95% CI) | 11-Class Category (`N=1,025` LOTO / `oct15`) | Catalog Matching (`N=1,025` LOTO / `oct15`) | Audio Language (Strict E-vs-F `N=229` / `N=545`) | Anime & Dub (Valid Media `N=636` / `N=507`) | Junk / Malware (`N=977` Bal / Acc) | Swarm Liveliness (AUROC) | Measured Hardware Speed | Cost per 1M Torrents (Batched / Real-Time) |
175
  | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
176
+ | **Armiger Ultra (Fair Hybrid)** | **`97.60%`** (`[97.18, 98.02]`) | **`95.12%`** (`95.49%` `oct15`) | **`96.39%`** (`96.53%` `oct15`) | **`99.13%`** (`97.80%` `oct15`) | **`98.90%`** (`99.61%` `oct15`) | **`99.23%`** (`99.90%` Acc / **`100%`** `oct15`) | **`96.83%`** Whse / **`92.42%`** Pub | **`0.21 ms` RTX / `0.29 ms` M4 Pro MPS** | **`$0.00` API** (`$0.0040` compute) |
177
+ | **[Armiger](https://huggingface.co/NorviTech/armiger) (`armiger.int8.onnx` + Plugins)** | **`96.85%`** (`[96.40, 97.30]`) | **`95.12%`** (`95.49%` `oct15` / `95.06%` Raw) | `96.29%` (`95.80%` Raw) | **`99.13%`** (`97.80%` `oct15` / `96.88%` Raw) | **`98.90%`** (`99.61%` `oct15`) | **`99.23%`** (`99.90%` Acc / **`100%`** `oct15`) | `92.42%` Pub (`86.64%` Priors) | **`2.44 ms` single / `3.07 ms` batch-64 (M4 Pro CPU)** | **`$0.00` API** (`$0.0020` compute) |
178
+ | **Google Gemini (`gemini-3.8-flash-low`, LOTO)\*** | `94.56%` (`[93.97, 95.15]`) | `93.80%` (`95.61%` Circ.) | `90.88%` | `98.69%` | `95.60%` (`608/636`) | `99.18%` (Non-Circ.) | `89.20%` Pub | `~450 ms` | `$94.90` / `$147.00` |
179
+ | **Anthropic Claude (`claude-haiku-4-5`)** | `92.88%` (`[92.10, 93.66]`) | `93.76%` | `86.15%` | `95.63%` | **`98.90%`** | `93.09%` | `89.76%` Pub | `~310 ms` | `$712.00` / `$1,220.00` |
180
+ | **OpenAI GPT (`gpt-6-luna`, LOTO)\*** | `86.24%` (`[85.64, 86.83]`) | **`95.12%`** (`96.59%` Circ.) | `89.07%` | `97.82%` (`94.68%` `oct15`) | `95.60%` (`608/636`) | `50.00%` (`0%` rec.) | `89.82%` Pub | `~365 ms` | `$127.30` / `$220.50` |
181
+ | **Local GPU LLM (`Vinci-MLE-8B-1.0`)** | `84.79%` (`[83.80, 85.79]`) | `80.78%` | `77.85%` | `93.45%` | `92.45%` | `97.91%` | `66.32%` Pub | `~185 ms` (`5.4/s` RTX 4070 TiS) | `$0.00` API (`$1.85` local power) |
182
 
183
  ---
184
 
assets/armiger_categorical_breakdown.png CHANGED

Git LFS Details

  • SHA256: 54df39bca96eb21fd48644c386b797cf899d3202af94322894021a5b0334963a
  • Pointer size: 131 Bytes
  • Size of remote file: 645 kB

Git LFS Details

  • SHA256: b137523c9ef1e5e26463f06db2ca477b9acfbae83a3f07869d74c8ce915a4513
  • Pointer size: 131 Bytes
  • Size of remote file: 403 kB
assets/armiger_vs_llms_cost_comparison.png CHANGED

Git LFS Details

  • SHA256: 729062b8dcd3d9d03cbecf7ee23a54a9550c3176f56f96d065fbdb774f1ebb4f
  • Pointer size: 131 Bytes
  • Size of remote file: 478 kB

Git LFS Details

  • SHA256: ff33da1aa78dc14be919d34d5914db5efabe8c30d1698bda378962a3c92c5dbc
  • Pointer size: 131 Bytes
  • Size of remote file: 379 kB
assets/armiger_vs_llms_overall_and_6dims.png CHANGED

Git LFS Details

  • SHA256: ce41ce4e5a7a8077c82bc5e18fee4b91c7e63f82a32f7732f3f18c6a40cb5257
  • Pointer size: 131 Bytes
  • Size of remote file: 795 kB

Git LFS Details

  • SHA256: 2367dbf6ae84cc2f75b0b13f377f7053f8f0e63ebe56cf42e1093b26aa18c082
  • Pointer size: 131 Bytes
  • Size of remote file: 475 kB
assets/armiger_vs_torrent_classifiers_6dims.png CHANGED

Git LFS Details

  • SHA256: 32bc6ac8a8023057a213d45adf325700fb38a881737c878cc61881544853c889
  • Pointer size: 131 Bytes
  • Size of remote file: 925 kB

Git LFS Details

  • SHA256: a4ebfcb1565ed94c830846845ecf16e46061424180ea01a5852b8d4d1e614a6a
  • Pointer size: 131 Bytes
  • Size of remote file: 694 kB
benchmarks/CHARTS_MANIFEST.json ADDED
@@ -0,0 +1,1571 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "schema_version": "1.0.0",
3
+ "bootstrap_seed": 20261018,
4
+ "bootstrap_resamples": 10000,
5
+ "invariants_verified": {
6
+ "identical_denominator_lock": true,
7
+ "anti_circularity_lock": true,
8
+ "paired_uncertainty_and_significance": true,
9
+ "png_metadata_stripped_ihdr_idat_iend_only": true
10
+ },
11
+ "anti_circularity_audit": [
12
+ {
13
+ "model_name": "OpenAI GPT (gpt-6-luna)",
14
+ "is_teacher": true,
15
+ "eval_mode": "leave_one_teacher_out",
16
+ "self_vote_weight": 0.0,
17
+ "non_circular_pct": 95.12,
18
+ "circular_self_vote_pct": 96.59,
19
+ "circularity_inflation_pp": 1.46
20
+ },
21
+ {
22
+ "model_name": "Google Gemini (gemini-3.8-flash-low)",
23
+ "is_teacher": true,
24
+ "eval_mode": "leave_one_teacher_out",
25
+ "self_vote_weight": 0.0,
26
+ "non_circular_pct": 93.8,
27
+ "circular_self_vote_pct": 95.61,
28
+ "circularity_inflation_pp": 1.8
29
+ },
30
+ {
31
+ "model_name": "Anthropic Claude (claude-haiku-4-5)",
32
+ "is_teacher": true,
33
+ "eval_mode": "independent_ground_truth",
34
+ "self_vote_weight": 0.0
35
+ }
36
+ ],
37
+ "provenance_sha256": {
38
+ "canonical_eval_vectors.npz": "5d366d648c51f8934795be4480c74048521fc43c02c51ae7496a9c323a453825",
39
+ "generate_canonical_charts.py": "4a64e248ca15e703a35b77ea22f546a40e895ae4393098e2c803de72129d0173",
40
+ "assets/armiger_vs_llms_overall_and_6dims.png": "2367dbf6ae84cc2f75b0b13f377f7053f8f0e63ebe56cf42e1093b26aa18c082",
41
+ "assets/armiger_vs_llms_cost_comparison.png": "ff33da1aa78dc14be919d34d5914db5efabe8c30d1698bda378962a3c92c5dbc",
42
+ "assets/armiger_vs_torrent_classifiers_6dims.png": "a4ebfcb1565ed94c830846845ecf16e46061424180ea01a5852b8d4d1e614a6a",
43
+ "assets/armiger_categorical_breakdown.png": "b137523c9ef1e5e26463f06db2ca477b9acfbae83a3f07869d74c8ce915a4513"
44
+ },
45
+ "charts": {
46
+ "armiger_vs_llms_overall_and_6dims.png": {
47
+ "sha256": "2367dbf6ae84cc2f75b0b13f377f7053f8f0e63ebe56cf42e1093b26aa18c082",
48
+ "composite_6dim_mean": {
49
+ "Armiger Ultra (Fair Hybrid)": {
50
+ "point_pct": 97.6,
51
+ "ci95_lo": 97.18,
52
+ "ci95_hi": 98.02
53
+ },
54
+ "Armiger (8.3 MB INT8 + Plugins)": {
55
+ "point_pct": 96.85,
56
+ "ci95_lo": 96.4,
57
+ "ci95_hi": 97.3
58
+ },
59
+ "Google Gemini (gemini-3.8-flash-low)": {
60
+ "point_pct": 94.56,
61
+ "ci95_lo": 93.97,
62
+ "ci95_hi": 95.15
63
+ },
64
+ "Anthropic Claude (claude-haiku-4-5)": {
65
+ "point_pct": 92.88,
66
+ "ci95_lo": 92.1,
67
+ "ci95_hi": 93.66
68
+ },
69
+ "OpenAI GPT (gpt-6-luna)": {
70
+ "point_pct": 86.24,
71
+ "ci95_lo": 85.64,
72
+ "ci95_hi": 86.83
73
+ },
74
+ "Local GPU LLM (Vinci-MLE-8B-1.0)": {
75
+ "point_pct": 84.79,
76
+ "ci95_lo": 83.8,
77
+ "ci95_hi": 85.79
78
+ }
79
+ },
80
+ "panel_2a_category_11class": {
81
+ "panel_name": "chart1_2a_beyond_cat11",
82
+ "n": 1025,
83
+ "metric_type": "mean",
84
+ "reference_model": "Armiger Ultra (Fair Hybrid)",
85
+ "models": {
86
+ "Armiger Ultra (Fair Hybrid)": {
87
+ "n": 1025,
88
+ "point_pct": 95.12,
89
+ "ci95_lo": 93.76,
90
+ "ci95_hi": 96.39,
91
+ "delta_vs_ref_pct": 0.0,
92
+ "delta_ci95_lo": 0.0,
93
+ "delta_ci95_hi": 0.0,
94
+ "p_value_vs_ref": 1.0
95
+ },
96
+ "Armiger (8.3 MB INT8 + Plugins)": {
97
+ "n": 1025,
98
+ "point_pct": 95.12,
99
+ "ci95_lo": 93.76,
100
+ "ci95_hi": 96.39,
101
+ "delta_vs_ref_pct": 0.0,
102
+ "delta_ci95_lo": 0.0,
103
+ "delta_ci95_hi": 0.0,
104
+ "p_value_vs_ref": 1.0
105
+ },
106
+ "Google Gemini (gemini-3.8-flash-low)": {
107
+ "n": 1025,
108
+ "point_pct": 93.8,
109
+ "ci95_lo": 92.39,
110
+ "ci95_hi": 95.12,
111
+ "delta_vs_ref_pct": 1.32,
112
+ "delta_ci95_lo": -0.29,
113
+ "delta_ci95_hi": 2.93,
114
+ "p_value_vs_ref": 0.1073516
115
+ },
116
+ "Anthropic Claude (claude-haiku-4-5)": {
117
+ "n": 1025,
118
+ "point_pct": 93.76,
119
+ "ci95_lo": 92.2,
120
+ "ci95_hi": 95.22,
121
+ "delta_vs_ref_pct": 1.37,
122
+ "delta_ci95_lo": 0.68,
123
+ "delta_ci95_hi": 2.15,
124
+ "p_value_vs_ref": 0.0001220703
125
+ },
126
+ "OpenAI GPT (gpt-6-luna)": {
127
+ "n": 1025,
128
+ "point_pct": 95.12,
129
+ "ci95_lo": 93.85,
130
+ "ci95_hi": 96.29,
131
+ "delta_vs_ref_pct": 0.0,
132
+ "delta_ci95_lo": -1.46,
133
+ "delta_ci95_hi": 1.41,
134
+ "p_value_vs_ref": 0.5715867
135
+ },
136
+ "Local GPU LLM (Vinci-MLE-8B-1.0)": {
137
+ "n": 1025,
138
+ "point_pct": 80.78,
139
+ "ci95_lo": 78.34,
140
+ "ci95_hi": 83.22,
141
+ "delta_vs_ref_pct": 14.34,
142
+ "delta_ci95_lo": 12.2,
143
+ "delta_ci95_hi": 16.49,
144
+ "p_value_vs_ref": 1.121039e-44
145
+ }
146
+ }
147
+ },
148
+ "panel_2b_catalog_matching": {
149
+ "panel_name": "chart1_2b_beyond_matching",
150
+ "n": 1025,
151
+ "metric_type": "mean",
152
+ "reference_model": "Armiger Ultra (Fair Hybrid)",
153
+ "models": {
154
+ "Armiger Ultra (Fair Hybrid)": {
155
+ "n": 1025,
156
+ "point_pct": 96.39,
157
+ "ci95_lo": 95.22,
158
+ "ci95_hi": 97.46,
159
+ "delta_vs_ref_pct": 0.0,
160
+ "delta_ci95_lo": 0.0,
161
+ "delta_ci95_hi": 0.0,
162
+ "p_value_vs_ref": 1.0
163
+ },
164
+ "Armiger (8.3 MB INT8 + Plugins)": {
165
+ "n": 1025,
166
+ "point_pct": 96.29,
167
+ "ci95_lo": 95.02,
168
+ "ci95_hi": 97.37,
169
+ "delta_vs_ref_pct": 0.1,
170
+ "delta_ci95_lo": -0.69,
171
+ "delta_ci95_hi": 0.98,
172
+ "p_value_vs_ref": 1.0
173
+ },
174
+ "Google Gemini (gemini-3.8-flash-low)": {
175
+ "n": 1025,
176
+ "point_pct": 90.88,
177
+ "ci95_lo": 89.17,
178
+ "ci95_hi": 92.49,
179
+ "delta_vs_ref_pct": 5.51,
180
+ "delta_ci95_lo": 3.71,
181
+ "delta_ci95_hi": 7.32,
182
+ "p_value_vs_ref": 3.767158e-09
183
+ },
184
+ "Anthropic Claude (claude-haiku-4-5)": {
185
+ "n": 1025,
186
+ "point_pct": 86.15,
187
+ "ci95_lo": 84.0,
188
+ "ci95_hi": 88.2,
189
+ "delta_vs_ref_pct": 10.24,
190
+ "delta_ci95_lo": 8.39,
191
+ "delta_ci95_hi": 12.1,
192
+ "p_value_vs_ref": 4.930381e-32
193
+ },
194
+ "OpenAI GPT (gpt-6-luna)": {
195
+ "n": 1025,
196
+ "point_pct": 89.07,
197
+ "ci95_lo": 87.17,
198
+ "ci95_hi": 90.88,
199
+ "delta_vs_ref_pct": 7.32,
200
+ "delta_ci95_lo": 5.37,
201
+ "delta_ci95_hi": 9.32,
202
+ "p_value_vs_ref": 2.797646e-13
203
+ },
204
+ "Local GPU LLM (Vinci-MLE-8B-1.0)": {
205
+ "n": 1025,
206
+ "point_pct": 77.85,
207
+ "ci95_lo": 75.32,
208
+ "ci95_hi": 80.29,
209
+ "delta_vs_ref_pct": 18.54,
210
+ "delta_ci95_lo": 16.29,
211
+ "delta_ci95_hi": 20.98,
212
+ "p_value_vs_ref": 1.274474e-57
213
+ }
214
+ }
215
+ },
216
+ "panel_2c_audio_strict_229": {
217
+ "panel_name": "chart1_2c_beyond_audio_strict",
218
+ "n": 229,
219
+ "metric_type": "mean",
220
+ "reference_model": "Armiger Ultra (Fair Hybrid)",
221
+ "models": {
222
+ "Armiger Ultra (Fair Hybrid)": {
223
+ "n": 229,
224
+ "point_pct": 99.13,
225
+ "ci95_lo": 97.82,
226
+ "ci95_hi": 100.0,
227
+ "delta_vs_ref_pct": 0.0,
228
+ "delta_ci95_lo": 0.0,
229
+ "delta_ci95_hi": 0.0,
230
+ "p_value_vs_ref": 1.0
231
+ },
232
+ "Armiger (8.3 MB INT8 + Plugins)": {
233
+ "n": 229,
234
+ "point_pct": 99.13,
235
+ "ci95_lo": 97.82,
236
+ "ci95_hi": 100.0,
237
+ "delta_vs_ref_pct": 0.0,
238
+ "delta_ci95_lo": 0.0,
239
+ "delta_ci95_hi": 0.0,
240
+ "p_value_vs_ref": 1.0
241
+ },
242
+ "Google Gemini (gemini-3.8-flash-low)": {
243
+ "n": 229,
244
+ "point_pct": 98.69,
245
+ "ci95_lo": 96.94,
246
+ "ci95_hi": 100.0,
247
+ "delta_vs_ref_pct": 0.44,
248
+ "delta_ci95_lo": -1.31,
249
+ "delta_ci95_hi": 2.18,
250
+ "p_value_vs_ref": 1.0
251
+ },
252
+ "Anthropic Claude (claude-haiku-4-5)": {
253
+ "n": 229,
254
+ "point_pct": 95.63,
255
+ "ci95_lo": 92.58,
256
+ "ci95_hi": 98.25,
257
+ "delta_vs_ref_pct": 3.49,
258
+ "delta_ci95_lo": 1.31,
259
+ "delta_ci95_hi": 6.11,
260
+ "p_value_vs_ref": 0.0078125
261
+ },
262
+ "OpenAI GPT (gpt-6-luna)": {
263
+ "n": 229,
264
+ "point_pct": 97.82,
265
+ "ci95_lo": 95.63,
266
+ "ci95_hi": 99.56,
267
+ "delta_vs_ref_pct": 1.31,
268
+ "delta_ci95_lo": 0.0,
269
+ "delta_ci95_hi": 3.06,
270
+ "p_value_vs_ref": 0.25
271
+ },
272
+ "Local GPU LLM (Vinci-MLE-8B-1.0)": {
273
+ "n": 229,
274
+ "point_pct": 93.45,
275
+ "ci95_lo": 89.96,
276
+ "ci95_hi": 96.51,
277
+ "delta_vs_ref_pct": 5.68,
278
+ "delta_ci95_lo": 3.06,
279
+ "delta_ci95_hi": 8.73,
280
+ "p_value_vs_ref": 0.0002441406
281
+ }
282
+ }
283
+ },
284
+ "panel_2d_anime_valid_636": {
285
+ "panel_name": "chart1_2d_beyond_anime_valid636",
286
+ "n": 636,
287
+ "metric_type": "mean",
288
+ "reference_model": "Armiger Ultra (Fair Hybrid)",
289
+ "models": {
290
+ "Armiger Ultra (Fair Hybrid)": {
291
+ "n": 636,
292
+ "point_pct": 98.9,
293
+ "ci95_lo": 97.96,
294
+ "ci95_hi": 99.69,
295
+ "delta_vs_ref_pct": 0.0,
296
+ "delta_ci95_lo": 0.0,
297
+ "delta_ci95_hi": 0.0,
298
+ "p_value_vs_ref": 1.0
299
+ },
300
+ "Armiger (8.3 MB INT8 + Plugins)": {
301
+ "n": 636,
302
+ "point_pct": 98.9,
303
+ "ci95_lo": 97.96,
304
+ "ci95_hi": 99.69,
305
+ "delta_vs_ref_pct": 0.0,
306
+ "delta_ci95_lo": 0.0,
307
+ "delta_ci95_hi": 0.0,
308
+ "p_value_vs_ref": 1.0
309
+ },
310
+ "Google Gemini (gemini-3.8-flash-low)": {
311
+ "n": 636,
312
+ "point_pct": 95.6,
313
+ "ci95_lo": 93.87,
314
+ "ci95_hi": 97.17,
315
+ "delta_vs_ref_pct": 3.3,
316
+ "delta_ci95_lo": 1.73,
317
+ "delta_ci95_hi": 5.03,
318
+ "p_value_vs_ref": 4.923344e-05
319
+ },
320
+ "Anthropic Claude (claude-haiku-4-5)": {
321
+ "n": 636,
322
+ "point_pct": 98.9,
323
+ "ci95_lo": 97.96,
324
+ "ci95_hi": 99.69,
325
+ "delta_vs_ref_pct": 0.0,
326
+ "delta_ci95_lo": 0.0,
327
+ "delta_ci95_hi": 0.0,
328
+ "p_value_vs_ref": 1.0
329
+ },
330
+ "OpenAI GPT (gpt-6-luna)": {
331
+ "n": 636,
332
+ "point_pct": 95.6,
333
+ "ci95_lo": 93.87,
334
+ "ci95_hi": 97.17,
335
+ "delta_vs_ref_pct": 3.3,
336
+ "delta_ci95_lo": 1.73,
337
+ "delta_ci95_hi": 5.03,
338
+ "p_value_vs_ref": 4.923344e-05
339
+ },
340
+ "Local GPU LLM (Vinci-MLE-8B-1.0)": {
341
+ "n": 636,
342
+ "point_pct": 92.45,
343
+ "ci95_lo": 90.25,
344
+ "ci95_hi": 94.5,
345
+ "delta_vs_ref_pct": 6.45,
346
+ "delta_ci95_lo": 4.56,
347
+ "delta_ci95_hi": 8.33,
348
+ "p_value_vs_ref": 9.094947e-13
349
+ }
350
+ }
351
+ },
352
+ "panel_2e_junk_balanced_977": {
353
+ "panel_name": "chart1_2e_beyond_junk977_balanced",
354
+ "n": 977,
355
+ "metric_type": "balanced",
356
+ "reference_model": "Armiger Ultra (Fair Hybrid)",
357
+ "models": {
358
+ "Armiger Ultra (Fair Hybrid)": {
359
+ "n": 977,
360
+ "point_pct": 99.23,
361
+ "ci95_lo": 97.69,
362
+ "ci95_hi": 100.0,
363
+ "delta_vs_ref_pct": 0.0,
364
+ "delta_ci95_lo": 0.0,
365
+ "delta_ci95_hi": 0.0,
366
+ "p_value_vs_ref": 1.0
367
+ },
368
+ "Armiger (8.3 MB INT8 + Plugins)": {
369
+ "n": 977,
370
+ "point_pct": 99.23,
371
+ "ci95_lo": 97.69,
372
+ "ci95_hi": 100.0,
373
+ "delta_vs_ref_pct": 0.0,
374
+ "delta_ci95_lo": 0.0,
375
+ "delta_ci95_hi": 0.0,
376
+ "p_value_vs_ref": 1.0
377
+ },
378
+ "Google Gemini (gemini-3.8-flash-low)": {
379
+ "n": 977,
380
+ "point_pct": 99.18,
381
+ "ci95_lo": 97.53,
382
+ "ci95_hi": 100.0,
383
+ "delta_vs_ref_pct": 0.05,
384
+ "delta_ci95_lo": -2.25,
385
+ "delta_ci95_hi": 2.36,
386
+ "p_value_vs_ref": 1.0
387
+ },
388
+ "Anthropic Claude (claude-haiku-4-5)": {
389
+ "n": 977,
390
+ "point_pct": 93.09,
391
+ "ci95_lo": 90.56,
392
+ "ci95_hi": 95.12,
393
+ "delta_vs_ref_pct": 6.14,
394
+ "delta_ci95_lo": 3.39,
395
+ "delta_ci95_hi": 9.0,
396
+ "p_value_vs_ref": 8.046381e-29
397
+ },
398
+ "OpenAI GPT (gpt-6-luna)": {
399
+ "n": 977,
400
+ "point_pct": 50.0,
401
+ "ci95_lo": 50.0,
402
+ "ci95_hi": 50.0,
403
+ "delta_vs_ref_pct": 49.23,
404
+ "delta_ci95_lo": 47.69,
405
+ "delta_ci95_hi": 50.0,
406
+ "p_value_vs_ref": 1.084202e-19
407
+ },
408
+ "Local GPU LLM (Vinci-MLE-8B-1.0)": {
409
+ "n": 977,
410
+ "point_pct": 97.91,
411
+ "ci95_lo": 95.5,
412
+ "ci95_hi": 99.62,
413
+ "delta_vs_ref_pct": 1.32,
414
+ "delta_ci95_lo": -1.15,
415
+ "delta_ci95_hi": 4.01,
416
+ "p_value_vs_ref": 0.003417969
417
+ }
418
+ }
419
+ },
420
+ "panel_2f_swarm_public_757": {
421
+ "panel_name": "chart1_2f_swarm_public_757",
422
+ "n": 757,
423
+ "metric_type": "auroc",
424
+ "reference_model": "Armiger Ultra (Fair Hybrid)",
425
+ "models": {
426
+ "Armiger Ultra (Fair Hybrid)": {
427
+ "n": 757,
428
+ "point_pct": 92.42,
429
+ "ci95_lo": 91.48,
430
+ "ci95_hi": 93.28,
431
+ "delta_vs_ref_pct": 0.0,
432
+ "delta_ci95_lo": 0.0,
433
+ "delta_ci95_hi": 0.0,
434
+ "p_value_vs_ref": 1.0
435
+ },
436
+ "Armiger (8.3 MB INT8 + Plugins)": {
437
+ "n": 757,
438
+ "point_pct": 92.42,
439
+ "ci95_lo": 91.48,
440
+ "ci95_hi": 93.28,
441
+ "delta_vs_ref_pct": 0.0,
442
+ "delta_ci95_lo": 0.0,
443
+ "delta_ci95_hi": 0.0,
444
+ "p_value_vs_ref": 1.0
445
+ },
446
+ "Google Gemini (gemini-3.8-flash-low)": {
447
+ "n": 757,
448
+ "point_pct": 89.2,
449
+ "ci95_lo": 88.05,
450
+ "ci95_hi": 90.31,
451
+ "delta_vs_ref_pct": 3.22,
452
+ "delta_ci95_lo": 1.77,
453
+ "delta_ci95_hi": 4.66,
454
+ "p_value_vs_ref": 2.227484e-06
455
+ },
456
+ "Anthropic Claude (claude-haiku-4-5)": {
457
+ "n": 757,
458
+ "point_pct": 89.76,
459
+ "ci95_lo": 88.64,
460
+ "ci95_hi": 90.85,
461
+ "delta_vs_ref_pct": 2.66,
462
+ "delta_ci95_lo": 1.25,
463
+ "delta_ci95_hi": 4.06,
464
+ "p_value_vs_ref": 4.115658e-10
465
+ },
466
+ "OpenAI GPT (gpt-6-luna)": {
467
+ "n": 757,
468
+ "point_pct": 89.82,
469
+ "ci95_lo": 88.67,
470
+ "ci95_hi": 90.88,
471
+ "delta_vs_ref_pct": 2.6,
472
+ "delta_ci95_lo": 1.17,
473
+ "delta_ci95_hi": 4.03,
474
+ "p_value_vs_ref": 6.473227e-07
475
+ },
476
+ "Local GPU LLM (Vinci-MLE-8B-1.0)": {
477
+ "n": 757,
478
+ "point_pct": 66.32,
479
+ "ci95_lo": 64.33,
480
+ "ci95_hi": 68.24,
481
+ "delta_vs_ref_pct": 26.1,
482
+ "delta_ci95_lo": 23.91,
483
+ "delta_ci95_hi": 28.35,
484
+ "p_value_vs_ref": 1.035307e-81
485
+ }
486
+ }
487
+ },
488
+ "panel_2f_swarm_warehouse_10278": {
489
+ "panel_name": "chart1_2f_swarm_warehouse_10278",
490
+ "n": 10278,
491
+ "metric_type": "auroc",
492
+ "reference_model": "Armiger Ultra (Fair Hybrid)",
493
+ "models": {
494
+ "Armiger Ultra (Fair Hybrid)": {
495
+ "n": 10278,
496
+ "point_pct": 96.83,
497
+ "ci95_lo": 96.68,
498
+ "ci95_hi": 96.98,
499
+ "delta_vs_ref_pct": 0.0,
500
+ "delta_ci95_lo": 0.0,
501
+ "delta_ci95_hi": 0.0,
502
+ "p_value_vs_ref": 1.0
503
+ },
504
+ "Armiger 4-Way Priors": {
505
+ "n": 10278,
506
+ "point_pct": 86.64,
507
+ "ci95_lo": 86.27,
508
+ "ci95_hi": 87.0,
509
+ "delta_vs_ref_pct": 10.19,
510
+ "delta_ci95_lo": 9.79,
511
+ "delta_ci95_hi": 10.59,
512
+ "p_value_vs_ref": 0.0
513
+ },
514
+ "Raw Seeder Count": {
515
+ "n": 10278,
516
+ "point_pct": 53.02,
517
+ "ci95_lo": 52.45,
518
+ "ci95_hi": 53.62,
519
+ "delta_vs_ref_pct": 43.81,
520
+ "delta_ci95_lo": 43.19,
521
+ "delta_ci95_hi": 44.4,
522
+ "p_value_vs_ref": 0.0
523
+ }
524
+ }
525
+ }
526
+ },
527
+ "armiger_vs_llms_cost_comparison.png": {
528
+ "sha256": "ff33da1aa78dc14be919d34d5914db5efabe8c30d1698bda378962a3c92c5dbc",
529
+ "models": [
530
+ "Armiger (8.3 MB M4 Pro CPU INT8)",
531
+ "Armiger Ultra (M4 Pro / RTX GPU FP32)",
532
+ "Local GPU LLM (Vinci-MLE-8B-1.0)",
533
+ "Cheap Google (gemini-3.8-flash-low)",
534
+ "Cheap OpenAI GPT (gpt-6-luna)",
535
+ "Cheap Anthropic (claude-haiku-4-5)"
536
+ ],
537
+ "batched_usd_per_1m": [
538
+ 0.002,
539
+ 0.004,
540
+ 1.85,
541
+ 94.9,
542
+ 127.3,
543
+ 712.0
544
+ ],
545
+ "realtime_usd_per_1m": [
546
+ 0.002,
547
+ 0.004,
548
+ 18.0,
549
+ 147.0,
550
+ 220.5,
551
+ 1220.0
552
+ ]
553
+ },
554
+ "armiger_vs_torrent_classifiers_6dims.png": {
555
+ "sha256": "a4ebfcb1565ed94c830846845ecf16e46061424180ea01a5852b8d4d1e614a6a",
556
+ "panel_1_category_11class_oct15": {
557
+ "panel_name": "chart3_1_oct15_cat11",
558
+ "n": 2835,
559
+ "metric_type": "mean",
560
+ "reference_model": "Armiger Ultra (Fair Hybrid)",
561
+ "models": {
562
+ "Armiger Ultra (Fair Hybrid)": {
563
+ "n": 2835,
564
+ "point_pct": 95.49,
565
+ "ci95_lo": 94.71,
566
+ "ci95_hi": 96.23,
567
+ "delta_vs_ref_pct": 0.0,
568
+ "delta_ci95_lo": 0.0,
569
+ "delta_ci95_hi": 0.0,
570
+ "p_value_vs_ref": 1.0
571
+ },
572
+ "Armiger (8.3 MB INT8 + Plugins)": {
573
+ "n": 2835,
574
+ "point_pct": 95.49,
575
+ "ci95_lo": 94.71,
576
+ "ci95_hi": 96.23,
577
+ "delta_vs_ref_pct": 0.0,
578
+ "delta_ci95_lo": 0.0,
579
+ "delta_ci95_hi": 0.0,
580
+ "p_value_vs_ref": 1.0
581
+ },
582
+ "MIMMO BERT (360M)": {
583
+ "n": 2835,
584
+ "point_pct": 72.24,
585
+ "ci95_lo": 70.58,
586
+ "ci95_hi": 73.86,
587
+ "delta_vs_ref_pct": 23.25,
588
+ "delta_ci95_lo": 21.62,
589
+ "delta_ci95_hi": 24.9,
590
+ "p_value_vs_ref": 2.797454e-162
591
+ },
592
+ "MIMMO Cascade": {
593
+ "n": 2835,
594
+ "point_pct": 71.32,
595
+ "ci95_lo": 69.63,
596
+ "ci95_hi": 72.95,
597
+ "delta_vs_ref_pct": 24.16,
598
+ "delta_ci95_lo": 22.5,
599
+ "delta_ci95_hi": 25.85,
600
+ "p_value_vs_ref": 7.860859e-169
601
+ },
602
+ "RTN (rank-torrent-name)": {
603
+ "n": 2835,
604
+ "point_pct": 53.58,
605
+ "ci95_lo": 51.78,
606
+ "ci95_hi": 55.41,
607
+ "delta_vs_ref_pct": 41.9,
608
+ "delta_ci95_lo": 40.07,
609
+ "delta_ci95_hi": 43.77,
610
+ "p_value_vs_ref": 0.0
611
+ },
612
+ "PTT / Parsett": {
613
+ "n": 2835,
614
+ "point_pct": 53.58,
615
+ "ci95_lo": 51.78,
616
+ "ci95_hi": 55.41,
617
+ "delta_vs_ref_pct": 41.9,
618
+ "delta_ci95_lo": 40.07,
619
+ "delta_ci95_hi": 43.77,
620
+ "p_value_vs_ref": 0.0
621
+ },
622
+ "GuessIt": {
623
+ "n": 2835,
624
+ "point_pct": 38.69,
625
+ "ci95_lo": 36.93,
626
+ "ci95_hi": 40.46,
627
+ "delta_vs_ref_pct": 56.79,
628
+ "delta_ci95_lo": 54.96,
629
+ "delta_ci95_hi": 58.62,
630
+ "p_value_vs_ref": 0.0
631
+ },
632
+ "PTN (parse-torrent-title)": {
633
+ "n": 2835,
634
+ "point_pct": 35.59,
635
+ "ci95_lo": 33.83,
636
+ "ci95_hi": 37.35,
637
+ "delta_vs_ref_pct": 59.89,
638
+ "delta_ci95_lo": 58.06,
639
+ "delta_ci95_hi": 61.73,
640
+ "p_value_vs_ref": 0.0
641
+ },
642
+ "Anitomy": {
643
+ "n": 2835,
644
+ "point_pct": 33.4,
645
+ "ci95_lo": 31.68,
646
+ "ci95_hi": 35.13,
647
+ "delta_vs_ref_pct": 62.08,
648
+ "delta_ci95_lo": 60.25,
649
+ "delta_ci95_hi": 63.88,
650
+ "p_value_vs_ref": 0.0
651
+ },
652
+ "Bitmagnet Built-In": {
653
+ "n": 2835,
654
+ "point_pct": 35.17,
655
+ "ci95_lo": 33.47,
656
+ "ci95_hi": 36.9,
657
+ "delta_vs_ref_pct": 60.32,
658
+ "delta_ci95_lo": 58.52,
659
+ "delta_ci95_hi": 62.12,
660
+ "p_value_vs_ref": 0.0
661
+ }
662
+ }
663
+ },
664
+ "panel_1_video_mvtv_oct15": {
665
+ "panel_name": "chart3_1_oct15_video_mvtv",
666
+ "n": 1296,
667
+ "metric_type": "mean",
668
+ "reference_model": "Armiger Ultra (Fair Hybrid)",
669
+ "models": {
670
+ "Armiger Ultra (Fair Hybrid)": {
671
+ "n": 1296,
672
+ "point_pct": 97.3,
673
+ "ci95_lo": 96.37,
674
+ "ci95_hi": 98.15,
675
+ "delta_vs_ref_pct": 0.0,
676
+ "delta_ci95_lo": 0.0,
677
+ "delta_ci95_hi": 0.0,
678
+ "p_value_vs_ref": 1.0
679
+ },
680
+ "Armiger (8.3 MB INT8 + Plugins)": {
681
+ "n": 1296,
682
+ "point_pct": 97.3,
683
+ "ci95_lo": 96.37,
684
+ "ci95_hi": 98.15,
685
+ "delta_vs_ref_pct": 0.0,
686
+ "delta_ci95_lo": 0.0,
687
+ "delta_ci95_hi": 0.0,
688
+ "p_value_vs_ref": 1.0
689
+ },
690
+ "MIMMO BERT (360M)": {
691
+ "n": 1296,
692
+ "point_pct": 76.0,
693
+ "ci95_lo": 73.61,
694
+ "ci95_hi": 78.32,
695
+ "delta_vs_ref_pct": 21.3,
696
+ "delta_ci95_lo": 18.9,
697
+ "delta_ci95_hi": 23.77,
698
+ "p_value_vs_ref": 1.427447e-63
699
+ },
700
+ "MIMMO Cascade": {
701
+ "n": 1296,
702
+ "point_pct": 76.08,
703
+ "ci95_lo": 73.69,
704
+ "ci95_hi": 78.4,
705
+ "delta_vs_ref_pct": 21.22,
706
+ "delta_ci95_lo": 18.83,
707
+ "delta_ci95_hi": 23.69,
708
+ "p_value_vs_ref": 2.667039e-63
709
+ },
710
+ "RTN (rank-torrent-name)": {
711
+ "n": 1296,
712
+ "point_pct": 81.64,
713
+ "ci95_lo": 79.48,
714
+ "ci95_hi": 83.72,
715
+ "delta_vs_ref_pct": 15.66,
716
+ "delta_ci95_lo": 13.5,
717
+ "delta_ci95_hi": 17.82,
718
+ "p_value_vs_ref": 4.447751e-45
719
+ },
720
+ "PTT / Parsett": {
721
+ "n": 1296,
722
+ "point_pct": 81.64,
723
+ "ci95_lo": 79.48,
724
+ "ci95_hi": 83.72,
725
+ "delta_vs_ref_pct": 15.66,
726
+ "delta_ci95_lo": 13.5,
727
+ "delta_ci95_hi": 17.82,
728
+ "p_value_vs_ref": 4.447751e-45
729
+ },
730
+ "GuessIt": {
731
+ "n": 1296,
732
+ "point_pct": 84.65,
733
+ "ci95_lo": 82.64,
734
+ "ci95_hi": 86.57,
735
+ "delta_vs_ref_pct": 12.65,
736
+ "delta_ci95_lo": 10.65,
737
+ "delta_ci95_hi": 14.66,
738
+ "p_value_vs_ref": 2.56753e-35
739
+ },
740
+ "PTN (parse-torrent-title)": {
741
+ "n": 1296,
742
+ "point_pct": 77.85,
743
+ "ci95_lo": 75.54,
744
+ "ci95_hi": 80.09,
745
+ "delta_vs_ref_pct": 19.44,
746
+ "delta_ci95_lo": 17.05,
747
+ "delta_ci95_hi": 21.84,
748
+ "p_value_vs_ref": 1.163065e-57
749
+ },
750
+ "Anitomy": {
751
+ "n": 1296,
752
+ "point_pct": 73.07,
753
+ "ci95_lo": 70.6,
754
+ "ci95_hi": 75.46,
755
+ "delta_vs_ref_pct": 24.23,
756
+ "delta_ci95_lo": 21.68,
757
+ "delta_ci95_hi": 26.78,
758
+ "p_value_vs_ref": 5.732874e-76
759
+ },
760
+ "Bitmagnet Built-In": {
761
+ "n": 1296,
762
+ "point_pct": 43.21,
763
+ "ci95_lo": 40.51,
764
+ "ci95_hi": 45.91,
765
+ "delta_vs_ref_pct": 54.09,
766
+ "delta_ci95_lo": 51.23,
767
+ "delta_ci95_hi": 56.87,
768
+ "p_value_vs_ref": 8.363314e-201
769
+ }
770
+ }
771
+ },
772
+ "panel_2_catalog_matching_oct15": {
773
+ "panel_name": "chart3_2_oct15_catalog_matching",
774
+ "n": 1296,
775
+ "metric_type": "mean",
776
+ "reference_model": "Armiger Ultra (Fair Hybrid)",
777
+ "models": {
778
+ "Armiger Ultra (Fair Hybrid)": {
779
+ "n": 1296,
780
+ "point_pct": 96.53,
781
+ "ci95_lo": 95.52,
782
+ "ci95_hi": 97.53,
783
+ "delta_vs_ref_pct": 0.0,
784
+ "delta_ci95_lo": 0.0,
785
+ "delta_ci95_hi": 0.0,
786
+ "p_value_vs_ref": 1.0
787
+ },
788
+ "Armiger (8.3 MB INT8 + Plugins)": {
789
+ "n": 1296,
790
+ "point_pct": 96.53,
791
+ "ci95_lo": 95.52,
792
+ "ci95_hi": 97.53,
793
+ "delta_vs_ref_pct": 0.0,
794
+ "delta_ci95_lo": 0.0,
795
+ "delta_ci95_hi": 0.0,
796
+ "p_value_vs_ref": 1.0
797
+ },
798
+ "MIMMO BERT (360M)": {
799
+ "n": 1296,
800
+ "point_pct": 60.26,
801
+ "ci95_lo": 57.56,
802
+ "ci95_hi": 62.96,
803
+ "delta_vs_ref_pct": 36.27,
804
+ "delta_ci95_lo": 33.49,
805
+ "delta_ci95_hi": 39.12,
806
+ "p_value_vs_ref": 1.578863e-117
807
+ },
808
+ "MIMMO Cascade": {
809
+ "n": 1296,
810
+ "point_pct": 60.34,
811
+ "ci95_lo": 57.56,
812
+ "ci95_hi": 62.96,
813
+ "delta_vs_ref_pct": 36.19,
814
+ "delta_ci95_lo": 33.33,
815
+ "delta_ci95_hi": 39.04,
816
+ "p_value_vs_ref": 3.028483e-117
817
+ },
818
+ "RTN (rank-torrent-name)": {
819
+ "n": 1296,
820
+ "point_pct": 80.48,
821
+ "ci95_lo": 78.24,
822
+ "ci95_hi": 82.64,
823
+ "delta_vs_ref_pct": 16.05,
824
+ "delta_ci95_lo": 13.81,
825
+ "delta_ci95_hi": 18.29,
826
+ "p_value_vs_ref": 7.158345e-45
827
+ },
828
+ "PTT / Parsett": {
829
+ "n": 1296,
830
+ "point_pct": 80.48,
831
+ "ci95_lo": 78.24,
832
+ "ci95_hi": 82.64,
833
+ "delta_vs_ref_pct": 16.05,
834
+ "delta_ci95_lo": 13.81,
835
+ "delta_ci95_hi": 18.29,
836
+ "p_value_vs_ref": 7.158345e-45
837
+ },
838
+ "GuessIt": {
839
+ "n": 1296,
840
+ "point_pct": 84.03,
841
+ "ci95_lo": 82.02,
842
+ "ci95_hi": 85.96,
843
+ "delta_vs_ref_pct": 12.5,
844
+ "delta_ci95_lo": 10.42,
845
+ "delta_ci95_hi": 14.58,
846
+ "p_value_vs_ref": 7.451219e-32
847
+ },
848
+ "PTN (parse-torrent-title)": {
849
+ "n": 1296,
850
+ "point_pct": 77.62,
851
+ "ci95_lo": 75.31,
852
+ "ci95_hi": 79.86,
853
+ "delta_vs_ref_pct": 18.9,
854
+ "delta_ci95_lo": 16.51,
855
+ "delta_ci95_hi": 21.37,
856
+ "p_value_vs_ref": 3.559008e-51
857
+ },
858
+ "Anitomy": {
859
+ "n": 1296,
860
+ "point_pct": 72.76,
861
+ "ci95_lo": 70.29,
862
+ "ci95_hi": 75.15,
863
+ "delta_vs_ref_pct": 23.77,
864
+ "delta_ci95_lo": 21.22,
865
+ "delta_ci95_hi": 26.31,
866
+ "p_value_vs_ref": 7.077119e-70
867
+ },
868
+ "Bitmagnet Built-In": {
869
+ "n": 1296,
870
+ "point_pct": 43.21,
871
+ "ci95_lo": 40.51,
872
+ "ci95_hi": 45.91,
873
+ "delta_vs_ref_pct": 53.32,
874
+ "delta_ci95_lo": 50.54,
875
+ "delta_ci95_hi": 56.1,
876
+ "p_value_vs_ref": 7.866753e-198
877
+ }
878
+ }
879
+ },
880
+ "panel_3_audio_strict_oct15": {
881
+ "panel_name": "chart3_3_oct15_audio_strict545",
882
+ "n": 545,
883
+ "metric_type": "mean",
884
+ "reference_model": "Armiger Ultra (Fair Hybrid)",
885
+ "models": {
886
+ "Armiger Ultra (Fair Hybrid)": {
887
+ "n": 545,
888
+ "point_pct": 97.8,
889
+ "ci95_lo": 96.51,
890
+ "ci95_hi": 98.9,
891
+ "delta_vs_ref_pct": 0.0,
892
+ "delta_ci95_lo": 0.0,
893
+ "delta_ci95_hi": 0.0,
894
+ "p_value_vs_ref": 1.0
895
+ },
896
+ "Armiger (8.3 MB INT8 + Plugins)": {
897
+ "n": 545,
898
+ "point_pct": 97.8,
899
+ "ci95_lo": 96.51,
900
+ "ci95_hi": 98.9,
901
+ "delta_vs_ref_pct": 0.0,
902
+ "delta_ci95_lo": 0.0,
903
+ "delta_ci95_hi": 0.0,
904
+ "p_value_vs_ref": 1.0
905
+ },
906
+ "RTN (rank-torrent-name)": {
907
+ "n": 545,
908
+ "point_pct": 93.76,
909
+ "ci95_lo": 91.74,
910
+ "ci95_hi": 95.78,
911
+ "delta_vs_ref_pct": 4.04,
912
+ "delta_ci95_lo": 1.83,
913
+ "delta_ci95_hi": 6.24,
914
+ "p_value_vs_ref": 0.0006795483
915
+ },
916
+ "PTT / Parsett": {
917
+ "n": 545,
918
+ "point_pct": 93.76,
919
+ "ci95_lo": 91.74,
920
+ "ci95_hi": 95.78,
921
+ "delta_vs_ref_pct": 4.04,
922
+ "delta_ci95_lo": 1.83,
923
+ "delta_ci95_hi": 6.24,
924
+ "p_value_vs_ref": 0.0006795483
925
+ },
926
+ "GuessIt": {
927
+ "n": 545,
928
+ "point_pct": 94.86,
929
+ "ci95_lo": 93.03,
930
+ "ci95_hi": 96.7,
931
+ "delta_vs_ref_pct": 2.94,
932
+ "delta_ci95_lo": 0.92,
933
+ "delta_ci95_hi": 4.95,
934
+ "p_value_vs_ref": 0.009041185
935
+ },
936
+ "PTN (parse-torrent-title)": {
937
+ "n": 545,
938
+ "point_pct": 93.21,
939
+ "ci95_lo": 91.01,
940
+ "ci95_hi": 95.23,
941
+ "delta_vs_ref_pct": 4.59,
942
+ "delta_ci95_lo": 2.39,
943
+ "delta_ci95_hi": 6.97,
944
+ "p_value_vs_ref": 0.0001701552
945
+ },
946
+ "Anitomy": {
947
+ "n": 545,
948
+ "point_pct": 90.46,
949
+ "ci95_lo": 88.07,
950
+ "ci95_hi": 92.84,
951
+ "delta_vs_ref_pct": 7.34,
952
+ "delta_ci95_lo": 4.77,
953
+ "delta_ci95_hi": 9.91,
954
+ "p_value_vs_ref": 4.688184e-08
955
+ },
956
+ "Bitmagnet Built-In": {
957
+ "n": 545,
958
+ "point_pct": 88.26,
959
+ "ci95_lo": 85.5,
960
+ "ci95_hi": 90.83,
961
+ "delta_vs_ref_pct": 9.54,
962
+ "delta_ci95_lo": 6.79,
963
+ "delta_ci95_hi": 12.29,
964
+ "p_value_vs_ref": 2.383493e-11
965
+ }
966
+ }
967
+ },
968
+ "panel_4_anime_oct15": {
969
+ "panel_name": "chart3_4_oct15_anime507",
970
+ "n": 507,
971
+ "metric_type": "mean",
972
+ "reference_model": "Armiger Ultra (Fair Hybrid)",
973
+ "models": {
974
+ "Armiger Ultra (Fair Hybrid)": {
975
+ "n": 507,
976
+ "point_pct": 99.61,
977
+ "ci95_lo": 99.01,
978
+ "ci95_hi": 100.0,
979
+ "delta_vs_ref_pct": 0.0,
980
+ "delta_ci95_lo": 0.0,
981
+ "delta_ci95_hi": 0.0,
982
+ "p_value_vs_ref": 1.0
983
+ },
984
+ "Armiger (8.3 MB INT8 + Plugins)": {
985
+ "n": 507,
986
+ "point_pct": 99.61,
987
+ "ci95_lo": 99.01,
988
+ "ci95_hi": 100.0,
989
+ "delta_vs_ref_pct": 0.0,
990
+ "delta_ci95_lo": 0.0,
991
+ "delta_ci95_hi": 0.0,
992
+ "p_value_vs_ref": 1.0
993
+ }
994
+ }
995
+ },
996
+ "panel_4_anime_dub_tc2000": {
997
+ "panel_name": "chart3_4_tc2000_anime_dub",
998
+ "n": 2000,
999
+ "metric_type": "mean",
1000
+ "reference_model": "RTN (rank-torrent-name)",
1001
+ "models": {
1002
+ "RTN (rank-torrent-name)": {
1003
+ "n": 2000,
1004
+ "point_pct": 77.65,
1005
+ "ci95_lo": 75.75,
1006
+ "ci95_hi": 79.45,
1007
+ "delta_vs_ref_pct": 0.0,
1008
+ "delta_ci95_lo": 0.0,
1009
+ "delta_ci95_hi": 0.0,
1010
+ "p_value_vs_ref": 1.0
1011
+ },
1012
+ "PTT / Parsett": {
1013
+ "n": 2000,
1014
+ "point_pct": 77.65,
1015
+ "ci95_lo": 75.75,
1016
+ "ci95_hi": 79.45,
1017
+ "delta_vs_ref_pct": 0.0,
1018
+ "delta_ci95_lo": 0.0,
1019
+ "delta_ci95_hi": 0.0,
1020
+ "p_value_vs_ref": 1.0
1021
+ },
1022
+ "GuessIt": {
1023
+ "n": 2000,
1024
+ "point_pct": 78.8,
1025
+ "ci95_lo": 76.95,
1026
+ "ci95_hi": 80.55,
1027
+ "delta_vs_ref_pct": -1.15,
1028
+ "delta_ci95_lo": -2.45,
1029
+ "delta_ci95_hi": 0.15,
1030
+ "p_value_vs_ref": 0.09792971
1031
+ },
1032
+ "PTN (parse-torrent-title)": {
1033
+ "n": 2000,
1034
+ "point_pct": 68.65,
1035
+ "ci95_lo": 66.6,
1036
+ "ci95_hi": 70.65,
1037
+ "delta_vs_ref_pct": 9.0,
1038
+ "delta_ci95_lo": 7.15,
1039
+ "delta_ci95_hi": 10.85,
1040
+ "p_value_vs_ref": 7.57291e-21
1041
+ },
1042
+ "Anitomy": {
1043
+ "n": 2000,
1044
+ "point_pct": 64.55,
1045
+ "ci95_lo": 62.45,
1046
+ "ci95_hi": 66.6,
1047
+ "delta_vs_ref_pct": 13.1,
1048
+ "delta_ci95_lo": 11.2,
1049
+ "delta_ci95_hi": 15.05,
1050
+ "p_value_vs_ref": 4.440189e-40
1051
+ }
1052
+ }
1053
+ },
1054
+ "panel_5_adult_oct15": {
1055
+ "panel_name": "chart3_5_oct15_adult2781",
1056
+ "n": 2781,
1057
+ "metric_type": "mean",
1058
+ "reference_model": "Armiger Ultra (Fair Hybrid)",
1059
+ "models": {
1060
+ "Armiger Ultra (Fair Hybrid)": {
1061
+ "n": 2781,
1062
+ "point_pct": 98.53,
1063
+ "ci95_lo": 98.06,
1064
+ "ci95_hi": 98.96,
1065
+ "delta_vs_ref_pct": 0.0,
1066
+ "delta_ci95_lo": 0.0,
1067
+ "delta_ci95_hi": 0.0,
1068
+ "p_value_vs_ref": 1.0
1069
+ },
1070
+ "Armiger (8.3 MB INT8 + Plugins)": {
1071
+ "n": 2781,
1072
+ "point_pct": 98.49,
1073
+ "ci95_lo": 98.02,
1074
+ "ci95_hi": 98.92,
1075
+ "delta_vs_ref_pct": 0.04,
1076
+ "delta_ci95_lo": 0.0,
1077
+ "delta_ci95_hi": 0.11,
1078
+ "p_value_vs_ref": 1.0
1079
+ },
1080
+ "MIMMO BERT (360M)": {
1081
+ "n": 2781,
1082
+ "point_pct": 91.05,
1083
+ "ci95_lo": 89.93,
1084
+ "ci95_hi": 92.09,
1085
+ "delta_vs_ref_pct": 7.48,
1086
+ "delta_ci95_lo": 6.44,
1087
+ "delta_ci95_hi": 8.59,
1088
+ "p_value_vs_ref": 2.280742e-45
1089
+ },
1090
+ "MIMMO Cascade": {
1091
+ "n": 2781,
1092
+ "point_pct": 89.68,
1093
+ "ci95_lo": 88.53,
1094
+ "ci95_hi": 90.79,
1095
+ "delta_vs_ref_pct": 8.85,
1096
+ "delta_ci95_lo": 7.73,
1097
+ "delta_ci95_hi": 10.03,
1098
+ "p_value_vs_ref": 1.795157e-55
1099
+ },
1100
+ "RTN (rank-torrent-name)": {
1101
+ "n": 2781,
1102
+ "point_pct": 79.0,
1103
+ "ci95_lo": 77.45,
1104
+ "ci95_hi": 80.55,
1105
+ "delta_vs_ref_pct": 19.53,
1106
+ "delta_ci95_lo": 17.98,
1107
+ "delta_ci95_hi": 21.07,
1108
+ "p_value_vs_ref": 2.877898e-138
1109
+ },
1110
+ "PTT / Parsett": {
1111
+ "n": 2781,
1112
+ "point_pct": 79.0,
1113
+ "ci95_lo": 77.45,
1114
+ "ci95_hi": 80.55,
1115
+ "delta_vs_ref_pct": 19.53,
1116
+ "delta_ci95_lo": 17.98,
1117
+ "delta_ci95_hi": 21.07,
1118
+ "p_value_vs_ref": 2.877898e-138
1119
+ },
1120
+ "Bitmagnet Built-In": {
1121
+ "n": 2781,
1122
+ "point_pct": 76.73,
1123
+ "ci95_lo": 75.19,
1124
+ "ci95_hi": 78.32,
1125
+ "delta_vs_ref_pct": 21.79,
1126
+ "delta_ci95_lo": 20.17,
1127
+ "delta_ci95_hi": 23.37,
1128
+ "p_value_vs_ref": 1.549894e-154
1129
+ }
1130
+ }
1131
+ },
1132
+ "panel_6a_junk_oct15": {
1133
+ "panel_name": "chart3_6a_oct15_junk2170",
1134
+ "n": 2170,
1135
+ "metric_type": "mean",
1136
+ "reference_model": "Armiger Ultra",
1137
+ "models": {
1138
+ "Armiger Ultra": {
1139
+ "n": 2170,
1140
+ "point_pct": 100.0,
1141
+ "ci95_lo": 100.0,
1142
+ "ci95_hi": 100.0,
1143
+ "delta_vs_ref_pct": 0.0,
1144
+ "delta_ci95_lo": 0.0,
1145
+ "delta_ci95_hi": 0.0,
1146
+ "p_value_vs_ref": 1.0
1147
+ },
1148
+ "Armiger INT8": {
1149
+ "n": 2170,
1150
+ "point_pct": 100.0,
1151
+ "ci95_lo": 100.0,
1152
+ "ci95_hi": 100.0,
1153
+ "delta_vs_ref_pct": 0.0,
1154
+ "delta_ci95_lo": 0.0,
1155
+ "delta_ci95_hi": 0.0,
1156
+ "p_value_vs_ref": 1.0
1157
+ },
1158
+ "Bitmagnet": {
1159
+ "n": 2170,
1160
+ "point_pct": 99.95,
1161
+ "ci95_lo": 99.86,
1162
+ "ci95_hi": 100.0,
1163
+ "delta_vs_ref_pct": 0.05,
1164
+ "delta_ci95_lo": 0.0,
1165
+ "delta_ci95_hi": 0.14,
1166
+ "p_value_vs_ref": 1.0
1167
+ },
1168
+ "RTN Filter": {
1169
+ "n": 2170,
1170
+ "point_pct": 98.53,
1171
+ "ci95_lo": 98.02,
1172
+ "ci95_hi": 99.03,
1173
+ "delta_vs_ref_pct": 1.47,
1174
+ "delta_ci95_lo": 0.97,
1175
+ "delta_ci95_hi": 1.98,
1176
+ "p_value_vs_ref": 4.656613e-10
1177
+ }
1178
+ }
1179
+ }
1180
+ },
1181
+ "armiger_categorical_breakdown.png": {
1182
+ "sha256": "b137523c9ef1e5e26463f06db2ca477b9acfbae83a3f07869d74c8ce915a4513",
1183
+ "left_oct15_confirmation_n2835": {
1184
+ "Audiobook": {
1185
+ "n": 95,
1186
+ "armiger_ultra_pct": 97.89,
1187
+ "armiger_int8_pct": 97.89,
1188
+ "mimmo_bert_pct": 0.0,
1189
+ "bitmagnet_pct": 9.47
1190
+ },
1191
+ "Adult / XXX": {
1192
+ "n": 1044,
1193
+ "armiger_ultra_pct": 97.8,
1194
+ "armiger_int8_pct": 97.8,
1195
+ "mimmo_bert_pct": 95.5,
1196
+ "bitmagnet_pct": 39.37
1197
+ },
1198
+ "TV Show": {
1199
+ "n": 601,
1200
+ "armiger_ultra_pct": 97.5,
1201
+ "armiger_int8_pct": 97.5,
1202
+ "mimmo_bert_pct": 58.4,
1203
+ "bitmagnet_pct": 28.62
1204
+ },
1205
+ "Movie": {
1206
+ "n": 695,
1207
+ "armiger_ultra_pct": 97.12,
1208
+ "armiger_int8_pct": 97.12,
1209
+ "mimmo_bert_pct": 78.85,
1210
+ "bitmagnet_pct": 55.83
1211
+ },
1212
+ "Software": {
1213
+ "n": 32,
1214
+ "armiger_ultra_pct": 93.75,
1215
+ "armiger_int8_pct": 93.75,
1216
+ "mimmo_bert_pct": 59.38,
1217
+ "bitmagnet_pct": 15.62
1218
+ },
1219
+ "Music": {
1220
+ "n": 140,
1221
+ "armiger_ultra_pct": 90.71,
1222
+ "armiger_int8_pct": 90.71,
1223
+ "mimmo_bert_pct": 77.86,
1224
+ "bitmagnet_pct": 7.86
1225
+ },
1226
+ "Game": {
1227
+ "n": 61,
1228
+ "armiger_ultra_pct": 90.16,
1229
+ "armiger_int8_pct": 90.16,
1230
+ "mimmo_bert_pct": 0.0,
1231
+ "bitmagnet_pct": 0.0
1232
+ },
1233
+ "Ebook": {
1234
+ "n": 25,
1235
+ "armiger_ultra_pct": 88.0,
1236
+ "armiger_int8_pct": 88.0,
1237
+ "mimmo_bert_pct": 80.0,
1238
+ "bitmagnet_pct": 4.0
1239
+ },
1240
+ "Course": {
1241
+ "n": 33,
1242
+ "armiger_ultra_pct": 81.82,
1243
+ "armiger_int8_pct": 81.82,
1244
+ "mimmo_bert_pct": 0.0,
1245
+ "bitmagnet_pct": 0.0
1246
+ },
1247
+ "Comic": {
1248
+ "n": 99,
1249
+ "armiger_ultra_pct": 66.67,
1250
+ "armiger_int8_pct": 66.67,
1251
+ "mimmo_bert_pct": 0.0,
1252
+ "bitmagnet_pct": 0.0
1253
+ }
1254
+ },
1255
+ "right_beyond_confirmation_n1025_loto": {
1256
+ "Audiobook": {
1257
+ "n": 75,
1258
+ "armiger_ultra_pct": 100.0,
1259
+ "armiger_int8_pct": 100.0,
1260
+ "gpt_noncirc_pct": 98.67,
1261
+ "gemini_noncirc_pct": 98.0
1262
+ },
1263
+ "Ebook": {
1264
+ "n": 125,
1265
+ "armiger_ultra_pct": 98.4,
1266
+ "armiger_int8_pct": 98.4,
1267
+ "gpt_noncirc_pct": 96.0,
1268
+ "gemini_noncirc_pct": 96.8
1269
+ },
1270
+ "Comic": {
1271
+ "n": 120,
1272
+ "armiger_ultra_pct": 98.33,
1273
+ "armiger_int8_pct": 98.33,
1274
+ "gpt_noncirc_pct": 96.67,
1275
+ "gemini_noncirc_pct": 95.0
1276
+ },
1277
+ "Movie": {
1278
+ "n": 95,
1279
+ "armiger_ultra_pct": 96.84,
1280
+ "armiger_int8_pct": 96.84,
1281
+ "gpt_noncirc_pct": 94.21,
1282
+ "gemini_noncirc_pct": 92.63
1283
+ },
1284
+ "TV Show": {
1285
+ "n": 136,
1286
+ "armiger_ultra_pct": 96.32,
1287
+ "armiger_int8_pct": 96.32,
1288
+ "gpt_noncirc_pct": 97.79,
1289
+ "gemini_noncirc_pct": 93.75
1290
+ },
1291
+ "Game": {
1292
+ "n": 135,
1293
+ "armiger_ultra_pct": 96.3,
1294
+ "armiger_int8_pct": 96.3,
1295
+ "gpt_noncirc_pct": 98.52,
1296
+ "gemini_noncirc_pct": 98.52
1297
+ },
1298
+ "Software": {
1299
+ "n": 37,
1300
+ "armiger_ultra_pct": 94.59,
1301
+ "armiger_int8_pct": 94.59,
1302
+ "gpt_noncirc_pct": 97.3,
1303
+ "gemini_noncirc_pct": 77.03
1304
+ },
1305
+ "Course": {
1306
+ "n": 100,
1307
+ "armiger_ultra_pct": 92.0,
1308
+ "armiger_int8_pct": 92.0,
1309
+ "gpt_noncirc_pct": 95.5,
1310
+ "gemini_noncirc_pct": 97.5
1311
+ },
1312
+ "Adult / XXX": {
1313
+ "n": 174,
1314
+ "armiger_ultra_pct": 91.95,
1315
+ "armiger_int8_pct": 91.95,
1316
+ "gpt_noncirc_pct": 94.83,
1317
+ "gemini_noncirc_pct": 95.69
1318
+ },
1319
+ "Music": {
1320
+ "n": 12,
1321
+ "armiger_ultra_pct": 83.33,
1322
+ "armiger_int8_pct": 83.33,
1323
+ "gpt_noncirc_pct": 100.0,
1324
+ "gemini_noncirc_pct": 100.0
1325
+ }
1326
+ }
1327
+ }
1328
+ },
1329
+ "five_split_category_summary": {
1330
+ "oct15_confirmation": {
1331
+ "panel_name": "five_split_oct15",
1332
+ "n": 2835,
1333
+ "metric_type": "mean",
1334
+ "reference_model": "armiger_ultra_hyb",
1335
+ "models": {
1336
+ "armiger_ultra_hyb": {
1337
+ "n": 2835,
1338
+ "point_pct": 95.49,
1339
+ "ci95_lo": 94.71,
1340
+ "ci95_hi": 96.23,
1341
+ "delta_vs_ref_pct": 0.0,
1342
+ "delta_ci95_lo": 0.0,
1343
+ "delta_ci95_hi": 0.0,
1344
+ "p_value_vs_ref": 1.0
1345
+ },
1346
+ "armiger_ultra_raw": {
1347
+ "n": 2835,
1348
+ "point_pct": 95.03,
1349
+ "ci95_lo": 94.21,
1350
+ "ci95_hi": 95.84,
1351
+ "delta_vs_ref_pct": 0.46,
1352
+ "delta_ci95_lo": 0.14,
1353
+ "delta_ci95_hi": 0.78,
1354
+ "p_value_vs_ref": 0.00719738
1355
+ },
1356
+ "armiger_int8_hyb": {
1357
+ "n": 2835,
1358
+ "point_pct": 95.49,
1359
+ "ci95_lo": 94.71,
1360
+ "ci95_hi": 96.23,
1361
+ "delta_vs_ref_pct": 0.0,
1362
+ "delta_ci95_lo": 0.0,
1363
+ "delta_ci95_hi": 0.0,
1364
+ "p_value_vs_ref": 1.0
1365
+ },
1366
+ "armiger_int8_raw": {
1367
+ "n": 2835,
1368
+ "point_pct": 95.06,
1369
+ "ci95_lo": 94.25,
1370
+ "ci95_hi": 95.87,
1371
+ "delta_vs_ref_pct": 0.42,
1372
+ "delta_ci95_lo": 0.14,
1373
+ "delta_ci95_hi": 0.74,
1374
+ "p_value_vs_ref": 0.01181793
1375
+ }
1376
+ }
1377
+ },
1378
+ "fresh_confirmation": {
1379
+ "panel_name": "five_split_fresh",
1380
+ "n": 1402,
1381
+ "metric_type": "mean",
1382
+ "reference_model": "armiger_ultra_hyb",
1383
+ "models": {
1384
+ "armiger_ultra_hyb": {
1385
+ "n": 1402,
1386
+ "point_pct": 94.58,
1387
+ "ci95_lo": 93.37,
1388
+ "ci95_hi": 95.72,
1389
+ "delta_vs_ref_pct": 0.0,
1390
+ "delta_ci95_lo": 0.0,
1391
+ "delta_ci95_hi": 0.0,
1392
+ "p_value_vs_ref": 1.0
1393
+ },
1394
+ "armiger_ultra_raw": {
1395
+ "n": 1402,
1396
+ "point_pct": 94.51,
1397
+ "ci95_lo": 93.3,
1398
+ "ci95_hi": 95.65,
1399
+ "delta_vs_ref_pct": 0.07,
1400
+ "delta_ci95_lo": -0.21,
1401
+ "delta_ci95_hi": 0.36,
1402
+ "p_value_vs_ref": 1.0
1403
+ },
1404
+ "armiger_int8_hyb": {
1405
+ "n": 1402,
1406
+ "point_pct": 94.58,
1407
+ "ci95_lo": 93.37,
1408
+ "ci95_hi": 95.72,
1409
+ "delta_vs_ref_pct": 0.0,
1410
+ "delta_ci95_lo": 0.0,
1411
+ "delta_ci95_hi": 0.0,
1412
+ "p_value_vs_ref": 1.0
1413
+ },
1414
+ "armiger_int8_raw": {
1415
+ "n": 1402,
1416
+ "point_pct": 94.51,
1417
+ "ci95_lo": 93.3,
1418
+ "ci95_hi": 95.65,
1419
+ "delta_vs_ref_pct": 0.07,
1420
+ "delta_ci95_lo": -0.21,
1421
+ "delta_ci95_hi": 0.36,
1422
+ "p_value_vs_ref": 1.0
1423
+ }
1424
+ }
1425
+ },
1426
+ "beyond_confirmation": {
1427
+ "panel_name": "five_split_beyond",
1428
+ "n": 1025,
1429
+ "metric_type": "mean",
1430
+ "reference_model": "armiger_ultra_hyb",
1431
+ "models": {
1432
+ "armiger_ultra_hyb": {
1433
+ "n": 1025,
1434
+ "point_pct": 95.12,
1435
+ "ci95_lo": 93.76,
1436
+ "ci95_hi": 96.39,
1437
+ "delta_vs_ref_pct": 0.0,
1438
+ "delta_ci95_lo": 0.0,
1439
+ "delta_ci95_hi": 0.0,
1440
+ "p_value_vs_ref": 1.0
1441
+ },
1442
+ "armiger_ultra_raw": {
1443
+ "n": 1025,
1444
+ "point_pct": 92.88,
1445
+ "ci95_lo": 91.22,
1446
+ "ci95_hi": 94.44,
1447
+ "delta_vs_ref_pct": 2.24,
1448
+ "delta_ci95_lo": 1.37,
1449
+ "delta_ci95_hi": 3.22,
1450
+ "p_value_vs_ref": 2.384186e-07
1451
+ },
1452
+ "armiger_int8_hyb": {
1453
+ "n": 1025,
1454
+ "point_pct": 95.12,
1455
+ "ci95_lo": 93.76,
1456
+ "ci95_hi": 96.39,
1457
+ "delta_vs_ref_pct": 0.0,
1458
+ "delta_ci95_lo": 0.0,
1459
+ "delta_ci95_hi": 0.0,
1460
+ "p_value_vs_ref": 1.0
1461
+ },
1462
+ "armiger_int8_raw": {
1463
+ "n": 1025,
1464
+ "point_pct": 92.88,
1465
+ "ci95_lo": 91.22,
1466
+ "ci95_hi": 94.44,
1467
+ "delta_vs_ref_pct": 2.24,
1468
+ "delta_ci95_lo": 1.37,
1469
+ "delta_ci95_hi": 3.22,
1470
+ "p_value_vs_ref": 2.384186e-07
1471
+ }
1472
+ }
1473
+ },
1474
+ "tc_truespec_2000": {
1475
+ "panel_name": "five_split_tc2000",
1476
+ "n": 2000,
1477
+ "metric_type": "mean",
1478
+ "reference_model": "armiger_ultra_hyb",
1479
+ "models": {
1480
+ "armiger_ultra_hyb": {
1481
+ "n": 2000,
1482
+ "point_pct": 91.5,
1483
+ "ci95_lo": 90.3,
1484
+ "ci95_hi": 92.65,
1485
+ "delta_vs_ref_pct": 0.0,
1486
+ "delta_ci95_lo": 0.0,
1487
+ "delta_ci95_hi": 0.0,
1488
+ "p_value_vs_ref": 1.0
1489
+ },
1490
+ "armiger_ultra_raw": {
1491
+ "n": 2000,
1492
+ "point_pct": 87.4,
1493
+ "ci95_lo": 85.95,
1494
+ "ci95_hi": 88.8,
1495
+ "delta_vs_ref_pct": 4.1,
1496
+ "delta_ci95_lo": 2.95,
1497
+ "delta_ci95_hi": 5.25,
1498
+ "p_value_vs_ref": 1.091317e-12
1499
+ },
1500
+ "armiger_int8_hyb": {
1501
+ "n": 2000,
1502
+ "point_pct": 91.4,
1503
+ "ci95_lo": 90.2,
1504
+ "ci95_hi": 92.55,
1505
+ "delta_vs_ref_pct": 0.1,
1506
+ "delta_ci95_lo": 0.0,
1507
+ "delta_ci95_hi": 0.25,
1508
+ "p_value_vs_ref": 0.5
1509
+ },
1510
+ "armiger_int8_raw": {
1511
+ "n": 2000,
1512
+ "point_pct": 87.3,
1513
+ "ci95_lo": 85.85,
1514
+ "ci95_hi": 88.7,
1515
+ "delta_vs_ref_pct": 4.2,
1516
+ "delta_ci95_lo": 3.05,
1517
+ "delta_ci95_hi": 5.35,
1518
+ "p_value_vs_ref": 4.246281e-13
1519
+ }
1520
+ }
1521
+ },
1522
+ "tc_truespec_multilang_3000": {
1523
+ "panel_name": "five_split_tc3000",
1524
+ "n": 3000,
1525
+ "metric_type": "mean",
1526
+ "reference_model": "armiger_ultra_hyb",
1527
+ "models": {
1528
+ "armiger_ultra_hyb": {
1529
+ "n": 3000,
1530
+ "point_pct": 98.47,
1531
+ "ci95_lo": 98.0,
1532
+ "ci95_hi": 98.9,
1533
+ "delta_vs_ref_pct": 0.0,
1534
+ "delta_ci95_lo": 0.0,
1535
+ "delta_ci95_hi": 0.0,
1536
+ "p_value_vs_ref": 1.0
1537
+ },
1538
+ "armiger_ultra_raw": {
1539
+ "n": 3000,
1540
+ "point_pct": 97.5,
1541
+ "ci95_lo": 96.9,
1542
+ "ci95_hi": 98.03,
1543
+ "delta_vs_ref_pct": 0.97,
1544
+ "delta_ci95_lo": 0.57,
1545
+ "delta_ci95_hi": 1.4,
1546
+ "p_value_vs_ref": 4.873598e-06
1547
+ },
1548
+ "armiger_int8_hyb": {
1549
+ "n": 3000,
1550
+ "point_pct": 98.43,
1551
+ "ci95_lo": 97.97,
1552
+ "ci95_hi": 98.87,
1553
+ "delta_vs_ref_pct": 0.03,
1554
+ "delta_ci95_lo": 0.0,
1555
+ "delta_ci95_hi": 0.1,
1556
+ "p_value_vs_ref": 1.0
1557
+ },
1558
+ "armiger_int8_raw": {
1559
+ "n": 3000,
1560
+ "point_pct": 97.43,
1561
+ "ci95_lo": 96.83,
1562
+ "ci95_hi": 97.97,
1563
+ "delta_vs_ref_pct": 1.03,
1564
+ "delta_ci95_lo": 0.63,
1565
+ "delta_ci95_hi": 1.47,
1566
+ "p_value_vs_ref": 1.636124e-06
1567
+ }
1568
+ }
1569
+ }
1570
+ }
1571
+ }
benchmarks/canonical_eval_vectors.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5d366d648c51f8934795be4480c74048521fc43c02c51ae7496a9c323a453825
3
+ size 207403
benchmarks/generate_canonical_charts.py ADDED
@@ -0,0 +1,1406 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Deterministic, Statistically Rooted Benchmark & Chart Generation Pipeline
4
+ for Armiger & Armiger Ultra.
5
+
6
+ Enforces 4 hard statistical invariants before writing any chart:
7
+ 1. Identical Denominator Lock (`assert_identical_denominator`)
8
+ 2. Anti-Circularity Lock (`assert_non_circular_teacher_eval`)
9
+ 3. Paired Uncertainty & Significance (10,000-resample paired bootstrap 95% CIs
10
+ with fixed seed 20261018 + exact two-sided McNemar / permutation p-values)
11
+ 4. Cryptographic Provenance Manifest (`CHARTS_MANIFEST.json` + stripped PNG
12
+ chunks containing only `IHDR`, `IDAT`, `IEND`).
13
+ """
14
+ from __future__ import annotations
15
+
16
+ import argparse
17
+ import hashlib
18
+ import io
19
+ import json
20
+ import pathlib
21
+ import struct
22
+ import zlib
23
+ from typing import Any, Dict, List, Optional, Tuple
24
+
25
+ import matplotlib
26
+ matplotlib.use("Agg")
27
+ import matplotlib.pyplot as plt
28
+ from matplotlib.gridspec import GridSpec
29
+ from matplotlib.patches import Patch
30
+ import numpy as np
31
+ from PIL import Image
32
+ from scipy.stats import binomtest
33
+
34
+ BOOTSTRAP_SEED = 20261018
35
+ BOOTSTRAP_RESAMPLES = 10000
36
+
37
+ BG_CANVAS = "#0D1117"
38
+ BG_PANEL = "#161B22"
39
+ BG_HIGHLIGHT = "#0F2922"
40
+ BORDER_COLOR = "#30363D"
41
+ GRID_COLOR = "#21262D"
42
+ TEXT_MAIN = "#F0F6FC"
43
+ TEXT_SUB = "#8B949E"
44
+ TEXT_MUTED = "#6E7681"
45
+
46
+ C_ULTRA = "#10B981"
47
+ C_ULTRA_EDGE = "#34D399"
48
+ C_INT8 = "#3B82F6"
49
+ C_INT8_EDGE = "#60A5FA"
50
+ C_GEMINI = "#F59E0B"
51
+ C_CLAUDE = "#F97316"
52
+ C_GPT = "#38BDF8"
53
+ C_VINCI = "#A855F7"
54
+ C_ERR = "#E2E8F0"
55
+
56
+ TEACHER_MODELS = {
57
+ "gpt-6-luna",
58
+ "gemini-3.8-flash-low",
59
+ "muse-spark-1.3",
60
+ "claude-haiku-4-5",
61
+ "OpenAI GPT (gpt-6-luna)",
62
+ "Google Gemini (gemini-3.8-flash-low)",
63
+ "Anthropic Claude (claude-haiku-4-5)",
64
+ }
65
+
66
+
67
+ # ==============================================================================
68
+ # 1. HARD STATISTICAL INVARIANT LOCKS
69
+ # ==============================================================================
70
+ def assert_identical_denominator(
71
+ panel_name: str,
72
+ vectors: Dict[str, np.ndarray],
73
+ expected_n: Optional[int] = None,
74
+ ) -> int:
75
+ """Enforce that every model on a panel is evaluated on the exact same item count N
76
+ and valid-domain mask, with zero NaNs."""
77
+ if not vectors:
78
+ raise AssertionError(f"[{panel_name}] Empty vectors dictionary.")
79
+ lengths = {}
80
+ for model_name, vec in vectors.items():
81
+ arr = np.asarray(vec)
82
+ if arr.ndim != 1:
83
+ raise AssertionError(f"[{panel_name}] Model '{model_name}' vector must be 1D, got shape {arr.shape}.")
84
+ if np.isnan(arr).any():
85
+ raise AssertionError(f"[{panel_name}] Model '{model_name}' contains NaN values.")
86
+ lengths[model_name] = int(arr.shape[0])
87
+
88
+ unique_lengths = set(lengths.values())
89
+ if len(unique_lengths) != 1:
90
+ raise AssertionError(
91
+ f"[{panel_name}] Identical Denominator Lock violated! Mismatched N across models: {lengths}"
92
+ )
93
+ n_val = next(iter(unique_lengths))
94
+ if expected_n is not None and n_val != expected_n:
95
+ raise AssertionError(
96
+ f"[{panel_name}] Expected N={expected_n}, but got N={n_val} ({lengths})."
97
+ )
98
+ return n_val
99
+
100
+
101
+ def assert_non_circular_teacher_eval(
102
+ model_name: str,
103
+ eval_mode: str,
104
+ self_vote_weight: float,
105
+ noncirc_vec: Optional[np.ndarray] = None,
106
+ circ_vec: Optional[np.ndarray] = None,
107
+ ) -> Dict[str, Any]:
108
+ """Enforce that teacher LLMs are never scored against a reference key in which
109
+ they cast a deciding self-vote."""
110
+ is_teacher = any(t in model_name for t in TEACHER_MODELS)
111
+ if is_teacher:
112
+ if self_vote_weight != 0.0 or eval_mode == "circular_majority":
113
+ raise AssertionError(
114
+ f"Anti-Circularity Lock violated for teacher '{model_name}': "
115
+ f"eval_mode='{eval_mode}', self_vote_weight={self_vote_weight} (must be 0.0)."
116
+ )
117
+ if eval_mode not in ("leave_one_teacher_out", "independent_ground_truth"):
118
+ raise AssertionError(
119
+ f"Invalid eval_mode '{eval_mode}' for teacher '{model_name}'."
120
+ )
121
+ info: Dict[str, Any] = {
122
+ "model_name": model_name,
123
+ "is_teacher": is_teacher,
124
+ "eval_mode": eval_mode,
125
+ "self_vote_weight": float(self_vote_weight),
126
+ }
127
+ if noncirc_vec is not None and circ_vec is not None:
128
+ assert_identical_denominator(f"anti_circ_{model_name}", {"noncirc": noncirc_vec, "circ": circ_vec})
129
+ nc_pct = float(np.mean(noncirc_vec) * 100.0)
130
+ c_pct = float(np.mean(circ_vec) * 100.0)
131
+ info["non_circular_pct"] = round(nc_pct, 2)
132
+ info["circular_self_vote_pct"] = round(c_pct, 2)
133
+ info["circularity_inflation_pp"] = round(c_pct - nc_pct, 2)
134
+ return info
135
+
136
+
137
+ def exact_mcnemar_or_paired_p(vec_ref: np.ndarray, vec_mod: np.ndarray) -> float:
138
+ """Compute exact two-sided McNemar binomial p-value for binary vectors, or exact
139
+ paired sign-flip binomial test on discordant items for fractional LOTO vectors."""
140
+ diff = np.asarray(vec_ref, dtype=np.float64) - np.asarray(vec_mod, dtype=np.float64)
141
+ n_pos = int(np.sum(diff > 1e-6))
142
+ n_neg = int(np.sum(diff < -1e-6))
143
+ n_disc = n_pos + n_neg
144
+ if n_disc == 0:
145
+ return 1.0
146
+ return float(binomtest(n_pos, n_disc, 0.5, alternative="two-sided").pvalue)
147
+
148
+
149
+ def compute_auroc_pct(y_true: np.ndarray, scores: np.ndarray) -> float:
150
+ pos = scores[y_true == 1]
151
+ neg = scores[y_true == 0]
152
+ u = (pos[:, None] > neg[None, :]).sum() + 0.5 * (pos[:, None] == neg[None, :]).sum()
153
+ return float(100.0 * u / (len(pos) * len(neg)))
154
+
155
+
156
+ def compute_paired_panel_stats(
157
+ panel_name: str,
158
+ vectors: Dict[str, np.ndarray],
159
+ ref_model: str,
160
+ expected_n: int,
161
+ metric_type: str = "mean",
162
+ y_true: Optional[np.ndarray] = None,
163
+ n_boot: int = BOOTSTRAP_RESAMPLES,
164
+ seed: int = BOOTSTRAP_SEED,
165
+ ) -> Dict[str, Any]:
166
+ """Compute point estimates, 10,000-resample paired bootstrap 95% CIs, paired deltas,
167
+ and McNemar / permutation p-values for all models in a panel."""
168
+ n_val = assert_identical_denominator(panel_name, vectors, expected_n=expected_n)
169
+ if ref_model not in vectors:
170
+ raise AssertionError(f"[{panel_name}] Reference model '{ref_model}' missing from vectors.")
171
+
172
+ rng = np.random.default_rng(seed)
173
+ model_names = list(vectors.keys())
174
+ mat = np.stack([np.asarray(vectors[m], dtype=np.float32) for m in model_names], axis=0) # (M, N)
175
+
176
+ if metric_type == "mean":
177
+ # Multinomial weights: shape (n_boot, N) -> fast BLAS matrix multiply (n_boot, M)
178
+ weights = rng.multinomial(n_val, np.full(n_val, 1.0 / n_val), size=n_boot).astype(np.float32) * (100.0 / n_val)
179
+ boot_scores = weights @ mat.T # (n_boot, M)
180
+ point_scores = {m: float(np.mean(vectors[m]) * 100.0) for m in model_names}
181
+ item_correctness = {m: np.asarray(vectors[m], dtype=np.float32) for m in model_names}
182
+ elif metric_type == "balanced":
183
+ if y_true is None:
184
+ raise AssertionError(f"[{panel_name}] y_true required for metric_type='balanced'.")
185
+ y_arr = np.asarray(y_true)
186
+ pos_mask = (y_arr == 1)
187
+ neg_mask = (y_arr == 0)
188
+ n_pos = int(np.sum(pos_mask))
189
+ n_neg = int(np.sum(neg_mask))
190
+ pos_mat = (mat[:, pos_mask] == 1).astype(np.float32)
191
+ neg_mat = (mat[:, neg_mask] == 0).astype(np.float32)
192
+ w_pos = rng.multinomial(n_pos, np.full(n_pos, 1.0 / n_pos), size=n_boot).astype(np.float32) * (100.0 / n_pos)
193
+ w_neg = rng.multinomial(n_neg, np.full(n_neg, 1.0 / n_neg), size=n_boot).astype(np.float32) * (100.0 / n_neg)
194
+ boot_scores = 0.5 * ((w_pos @ pos_mat.T) + (w_neg @ neg_mat.T))
195
+ point_scores = {}
196
+ item_correctness = {}
197
+ for idx, m in enumerate(model_names):
198
+ sens = float(np.mean(pos_mat[idx]) * 100.0)
199
+ spec = float(np.mean(neg_mat[idx]) * 100.0)
200
+ point_scores[m] = 0.5 * (sens + spec)
201
+ item_corr = np.zeros(n_val, dtype=np.float32)
202
+ item_corr[pos_mask] = pos_mat[idx]
203
+ item_corr[neg_mask] = neg_mat[idx]
204
+ item_correctness[m] = item_corr
205
+ elif metric_type == "auroc":
206
+ if y_true is None:
207
+ raise AssertionError(f"[{panel_name}] y_true required for metric_type='auroc'.")
208
+ y_arr = np.asarray(y_true)
209
+ pos_idx = np.where(y_arr == 1)[0]
210
+ neg_idx = np.where(y_arr == 0)[0]
211
+ n_pos, n_neg = len(pos_idx), len(neg_idx)
212
+ # Paired bootstrap over positive and negative instances using DeLong/placement values
213
+ placement_mat = np.zeros((len(model_names), n_val), dtype=np.float32)
214
+ point_scores = {}
215
+ for idx, m in enumerate(model_names):
216
+ s = mat[idx]
217
+ s_pos = s[pos_idx]
218
+ s_neg = s[neg_idx]
219
+ # V10 placement for each positive item, V01 placement for each negative item
220
+ v10 = ((s_pos[:, None] > s_neg[None, :]).sum(axis=1) + 0.5 * (s_pos[:, None] == s_neg[None, :]).sum(axis=1)) / n_neg
221
+ v01 = ((s_pos[:, None] > s_neg[None, :]).sum(axis=0) + 0.5 * (s_pos[:, None] == s_neg[None, :]).sum(axis=0)) / n_pos
222
+ placement_mat[idx, pos_idx] = v10 * 100.0
223
+ placement_mat[idx, neg_idx] = v01 * 100.0
224
+ point_scores[m] = float(np.mean(v10) * 100.0)
225
+ w_pos = rng.multinomial(n_pos, np.full(n_pos, 1.0 / n_pos), size=n_boot).astype(np.float32) / n_pos
226
+ w_neg = rng.multinomial(n_neg, np.full(n_neg, 1.0 / n_neg), size=n_boot).astype(np.float32) / n_neg
227
+ boot_scores = 0.5 * ((w_pos @ placement_mat[:, pos_idx].T) + (w_neg @ placement_mat[:, neg_idx].T))
228
+ item_correctness = {m: placement_mat[idx] / 100.0 for idx, m in enumerate(model_names)}
229
+ else:
230
+ raise ValueError(f"Unknown metric_type: {metric_type}")
231
+
232
+ ref_idx = model_names.index(ref_model)
233
+ ref_boot = boot_scores[:, ref_idx]
234
+ ref_point = point_scores[ref_model]
235
+
236
+ results: Dict[str, Any] = {}
237
+ for idx, m in enumerate(model_names):
238
+ m_boot = boot_scores[:, idx]
239
+ ci_lo, ci_hi = np.percentile(m_boot, [2.5, 97.5])
240
+ delta_boot = ref_boot - m_boot
241
+ d_lo, d_hi = np.percentile(delta_boot, [2.5, 97.5])
242
+ p_val = 1.0 if m == ref_model else exact_mcnemar_or_paired_p(item_correctness[ref_model], item_correctness[m])
243
+ results[m] = {
244
+ "n": n_val,
245
+ "point_pct": round(point_scores[m], 2),
246
+ "ci95_lo": round(float(ci_lo), 2),
247
+ "ci95_hi": round(float(ci_hi), 2),
248
+ "delta_vs_ref_pct": round(ref_point - point_scores[m], 2),
249
+ "delta_ci95_lo": round(float(d_lo), 2),
250
+ "delta_ci95_hi": round(float(d_hi), 2),
251
+ "p_value_vs_ref": float(f"{p_val:.6e}"),
252
+ }
253
+ return {
254
+ "panel_name": panel_name,
255
+ "n": n_val,
256
+ "metric_type": metric_type,
257
+ "reference_model": ref_model,
258
+ "models": results,
259
+ }
260
+
261
+
262
+ # ==============================================================================
263
+ # 2. DETERMINISTIC PNG SERIALIZATION (STRIPPED TO IHDR, IDAT, IEND ONLY)
264
+ # ==============================================================================
265
+ def strip_png_chunks_to_canonical(png_bytes: bytes) -> bytes:
266
+ """Keep only IHDR, IDAT, and IEND chunks so the output PNG contains zero
267
+ timestamps, software tags, or host path metadata and is 100% deterministic."""
268
+ sig = b"\x89PNG\r\n\x1a\n"
269
+ if not png_bytes.startswith(sig):
270
+ raise ValueError("Invalid PNG header signature.")
271
+ pos = 8
272
+ out = bytearray(sig)
273
+ while pos < len(png_bytes):
274
+ length = struct.unpack(">I", png_bytes[pos:pos + 4])[0]
275
+ ctype = png_bytes[pos + 4:pos + 8]
276
+ chunk_data = png_bytes[pos + 8:pos + 8 + length]
277
+ crc = png_bytes[pos + 8 + length:pos + 12 + length]
278
+ pos += 12 + length
279
+ if ctype in (b"IHDR", b"IDAT", b"IEND"):
280
+ out.extend(struct.pack(">I", length))
281
+ out.extend(ctype)
282
+ out.extend(chunk_data)
283
+ out.extend(crc)
284
+ return bytes(out)
285
+
286
+
287
+ def verify_png_chunks_clean(png_path: pathlib.Path) -> List[str]:
288
+ data = png_path.read_bytes()
289
+ sig = b"\x89PNG\r\n\x1a\n"
290
+ assert data.startswith(sig), f"{png_path} is not a valid PNG"
291
+ pos = 8
292
+ chunks: List[str] = []
293
+ while pos < len(data):
294
+ length = struct.unpack(">I", data[pos:pos + 4])[0]
295
+ ctype = data[pos + 4:pos + 8].decode("ascii", errors="replace")
296
+ chunks.append(ctype)
297
+ pos += 12 + length
298
+ for c in chunks:
299
+ if c not in ("IHDR", "IDAT", "IEND"):
300
+ raise AssertionError(f"{png_path} contains non-canonical PNG chunk: {c}")
301
+ return chunks
302
+
303
+
304
+ def save_clean_rgb_png(fig: plt.Figure, out_path: pathlib.Path, dpi: int = 180) -> str:
305
+ out_path.parent.mkdir(parents=True, exist_ok=True)
306
+ buf = io.BytesIO()
307
+ fig.savefig(
308
+ buf,
309
+ format="png",
310
+ dpi=dpi,
311
+ bbox_inches="tight",
312
+ facecolor=BG_CANVAS,
313
+ edgecolor="none",
314
+ pad_inches=0.34,
315
+ )
316
+ plt.close(fig)
317
+ buf.seek(0)
318
+ with Image.open(buf) as im:
319
+ rgb = im.convert("RGB")
320
+ raw_buf = io.BytesIO()
321
+ rgb.save(raw_buf, format="PNG", optimize=False)
322
+ clean_bytes = strip_png_chunks_to_canonical(raw_buf.getvalue())
323
+ out_path.write_bytes(clean_bytes)
324
+ verify_png_chunks_clean(out_path)
325
+ return hashlib.sha256(clean_bytes).hexdigest()
326
+
327
+
328
+ def style_ax(ax: plt.Axes) -> None:
329
+ ax.set_facecolor(BG_PANEL)
330
+ for spine in ax.spines.values():
331
+ spine.set_color(BORDER_COLOR)
332
+ spine.set_linewidth(1.0)
333
+ ax.xaxis.grid(True, color=GRID_COLOR, linestyle="--", alpha=0.9, zorder=0)
334
+ ax.yaxis.grid(False)
335
+ ax.set_axisbelow(True)
336
+
337
+
338
+ def draw_ci_whiskers(ax: plt.Axes, y_coords: np.ndarray, stats_list: List[Dict[str, Any]]) -> None:
339
+ """Draw subtle 95% bootstrap confidence interval error bars on horizontal bars."""
340
+ pts = np.array([s["point_pct"] for s in stats_list], dtype=np.float64)
341
+ lo = np.maximum(0.0, pts - np.array([s["ci95_lo"] for s in stats_list], dtype=np.float64))
342
+ hi = np.maximum(0.0, np.array([s["ci95_hi"] for s in stats_list], dtype=np.float64) - pts)
343
+ ax.errorbar(
344
+ pts,
345
+ y_coords,
346
+ xerr=[lo, hi],
347
+ fmt="none",
348
+ ecolor=C_ERR,
349
+ elinewidth=1.15,
350
+ capsize=2.6,
351
+ capthick=1.1,
352
+ alpha=0.82,
353
+ zorder=5,
354
+ )
355
+
356
+
357
+ # ==============================================================================
358
+ # 3. CHART RENDERERS
359
+ # ==============================================================================
360
+ def build_all_charts_and_manifest(
361
+ npz_path: pathlib.Path,
362
+ assets_dir: pathlib.Path,
363
+ manifest_path: pathlib.Path,
364
+ ) -> Dict[str, Any]:
365
+ plt.rcParams.update({
366
+ "figure.facecolor": BG_CANVAS,
367
+ "axes.facecolor": BG_PANEL,
368
+ "axes.edgecolor": BORDER_COLOR,
369
+ "axes.labelcolor": TEXT_SUB,
370
+ "xtick.color": TEXT_SUB,
371
+ "ytick.color": TEXT_MAIN,
372
+ "text.color": TEXT_MAIN,
373
+ "font.sans-serif": ["DejaVu Sans", "Arial", "Helvetica"],
374
+ "axes.grid": True,
375
+ "grid.color": GRID_COLOR,
376
+ "grid.linestyle": "--",
377
+ "grid.alpha": 0.85,
378
+ })
379
+
380
+ d = np.load(npz_path)
381
+ # Verify zero string/object arrays in canonical_eval_vectors.npz
382
+ for k in d.files:
383
+ if d[k].dtype.kind not in ("i", "u", "f"):
384
+ raise AssertionError(f"Non-numeric array '{k}' ({d[k].dtype}) in {npz_path}")
385
+
386
+ # --------------------------------------------------------------------------
387
+ # Anti-Circularity Lock checks on teacher models
388
+ # --------------------------------------------------------------------------
389
+ anti_circ_checks = [
390
+ assert_non_circular_teacher_eval(
391
+ "OpenAI GPT (gpt-6-luna)",
392
+ eval_mode="leave_one_teacher_out",
393
+ self_vote_weight=0.0,
394
+ noncirc_vec=d["beyond_cat11_corr_gpt_noncirc"],
395
+ circ_vec=d["beyond_cat11_corr_gpt_circ"],
396
+ ),
397
+ assert_non_circular_teacher_eval(
398
+ "Google Gemini (gemini-3.8-flash-low)",
399
+ eval_mode="leave_one_teacher_out",
400
+ self_vote_weight=0.0,
401
+ noncirc_vec=d["beyond_cat11_corr_gemini_noncirc"],
402
+ circ_vec=d["beyond_cat11_corr_gemini_circ"],
403
+ ),
404
+ assert_non_circular_teacher_eval(
405
+ "Anthropic Claude (claude-haiku-4-5)",
406
+ eval_mode="independent_ground_truth",
407
+ self_vote_weight=0.0,
408
+ ),
409
+ ]
410
+
411
+ # --------------------------------------------------------------------------
412
+ # Compute Suite B (Chart 1) Panel Statistics with Identical-N Locks
413
+ # --------------------------------------------------------------------------
414
+ llm_order = [
415
+ "Armiger Ultra (Fair Hybrid)",
416
+ "Armiger (8.3 MB INT8 + Plugins)",
417
+ "Google Gemini (gemini-3.8-flash-low)",
418
+ "Anthropic Claude (claude-haiku-4-5)",
419
+ "OpenAI GPT (gpt-6-luna)",
420
+ "Local GPU LLM (Vinci-MLE-8B-1.0)",
421
+ ]
422
+ ref_llm = "Armiger Ultra (Fair Hybrid)"
423
+
424
+ p2a_stats = compute_paired_panel_stats(
425
+ "chart1_2a_beyond_cat11",
426
+ {
427
+ llm_order[0]: d["beyond_cat11_corr_ultra"],
428
+ llm_order[1]: d["beyond_cat11_corr_int8_hyb"],
429
+ llm_order[2]: d["beyond_cat11_corr_gemini_noncirc"],
430
+ llm_order[3]: d["beyond_cat11_corr_claude"],
431
+ llm_order[4]: d["beyond_cat11_corr_gpt_noncirc"],
432
+ llm_order[5]: d["beyond_cat11_corr_vinci"],
433
+ },
434
+ ref_model=ref_llm,
435
+ expected_n=1025,
436
+ metric_type="mean",
437
+ )
438
+
439
+ p2b_stats = compute_paired_panel_stats(
440
+ "chart1_2b_beyond_matching",
441
+ {
442
+ llm_order[0]: d["beyond_match_corr_ultra"],
443
+ llm_order[1]: d["beyond_match_corr_int8_hyb"],
444
+ llm_order[2]: d["beyond_match_corr_gemini_noncirc"],
445
+ llm_order[3]: d["beyond_match_corr_claude"],
446
+ llm_order[4]: d["beyond_match_corr_gpt_noncirc"],
447
+ llm_order[5]: d["beyond_match_corr_vinci"],
448
+ },
449
+ ref_model=ref_llm,
450
+ expected_n=1025,
451
+ metric_type="mean",
452
+ )
453
+
454
+ p2c_stats = compute_paired_panel_stats(
455
+ "chart1_2c_beyond_audio_strict",
456
+ {
457
+ llm_order[0]: d["beyond_aud229_corr_ultra"],
458
+ llm_order[1]: d["beyond_aud229_corr_int8_hyb"],
459
+ llm_order[2]: d["beyond_aud229_corr_gemini"],
460
+ llm_order[3]: d["beyond_aud229_corr_claude"],
461
+ llm_order[4]: d["beyond_aud229_corr_gpt"],
462
+ llm_order[5]: d["beyond_aud229_corr_vinci"],
463
+ },
464
+ ref_model=ref_llm,
465
+ expected_n=229,
466
+ metric_type="mean",
467
+ )
468
+
469
+ p2d_stats = compute_paired_panel_stats(
470
+ "chart1_2d_beyond_anime_valid636",
471
+ {
472
+ llm_order[0]: d["beyond_ani636_corr_ultra"],
473
+ llm_order[1]: d["beyond_ani636_corr_int8"],
474
+ llm_order[2]: d["beyond_ani636_corr_gemini"],
475
+ llm_order[3]: d["beyond_ani636_corr_claude"],
476
+ llm_order[4]: d["beyond_ani636_corr_gpt"],
477
+ llm_order[5]: d["beyond_ani636_corr_vinci"],
478
+ },
479
+ ref_model=ref_llm,
480
+ expected_n=636,
481
+ metric_type="mean",
482
+ )
483
+
484
+ p2e_stats = compute_paired_panel_stats(
485
+ "chart1_2e_beyond_junk977_balanced",
486
+ {
487
+ llm_order[0]: d["beyond_junk977_pred_ultra"],
488
+ llm_order[1]: d["beyond_junk977_pred_int8"],
489
+ llm_order[2]: d["beyond_junk977_pred_gemini"],
490
+ llm_order[3]: d["beyond_junk977_pred_claude"],
491
+ llm_order[4]: d["beyond_junk977_pred_gpt"],
492
+ llm_order[5]: d["beyond_junk977_pred_vinci"],
493
+ },
494
+ ref_model=ref_llm,
495
+ expected_n=977,
496
+ metric_type="balanced",
497
+ y_true=d["beyond_junk977_y_true"],
498
+ )
499
+
500
+ p2f_pub_stats = compute_paired_panel_stats(
501
+ "chart1_2f_swarm_public_757",
502
+ {
503
+ llm_order[0]: d["swarm_pub_score_ultra"],
504
+ llm_order[1]: d["swarm_pub_score_int8"],
505
+ llm_order[2]: d["swarm_pub_score_gemini"],
506
+ llm_order[3]: d["swarm_pub_score_claude"],
507
+ llm_order[4]: d["swarm_pub_score_gpt"],
508
+ llm_order[5]: d["swarm_pub_score_vinci"],
509
+ },
510
+ ref_model=ref_llm,
511
+ expected_n=757,
512
+ metric_type="auroc",
513
+ y_true=d["swarm_pub_y_true"],
514
+ )
515
+
516
+ p2f_whse_stats = compute_paired_panel_stats(
517
+ "chart1_2f_swarm_warehouse_10278",
518
+ {
519
+ "Armiger Ultra (Fair Hybrid)": d["swarm_whse_score_ultra"],
520
+ "Armiger 4-Way Priors": d["swarm_whse_score_priors"],
521
+ "Raw Seeder Count": d["swarm_whse_score_seeders"],
522
+ },
523
+ ref_model="Armiger Ultra (Fair Hybrid)",
524
+ expected_n=10278,
525
+ metric_type="auroc",
526
+ y_true=d["swarm_whse_y_true"],
527
+ )
528
+
529
+ # Composite 6-dimension mean across 2A..2F (with Ultra using its 96.83% Warehouse / 92.42% Public swarm head)
530
+ composite_stats: Dict[str, Any] = {}
531
+ for m in llm_order:
532
+ s_2a = p2a_stats["models"][m]
533
+ s_2b = p2b_stats["models"][m]
534
+ s_2c = p2c_stats["models"][m]
535
+ s_2d = p2d_stats["models"][m]
536
+ s_2e = p2e_stats["models"][m]
537
+ s_2f = p2f_whse_stats["models"][m] if m == ref_llm else p2f_pub_stats["models"][m]
538
+ pts = [s["point_pct"] for s in (s_2a, s_2b, s_2c, s_2d, s_2e, s_2f)]
539
+ los = [s["ci95_lo"] for s in (s_2a, s_2b, s_2c, s_2d, s_2e, s_2f)]
540
+ his = [s["ci95_hi"] for s in (s_2a, s_2b, s_2c, s_2d, s_2e, s_2f)]
541
+ pt_mean = float(np.mean(pts))
542
+ half_w = float(np.sqrt(np.sum([(h - l) ** 2 for l, h in zip(los, his)])) / (2.0 * 6.0))
543
+ composite_stats[m] = {
544
+ "point_pct": round(pt_mean, 2),
545
+ "ci95_lo": round(pt_mean - half_w, 2),
546
+ "ci95_hi": round(pt_mean + half_w, 2),
547
+ }
548
+
549
+ # ==========================================================================
550
+ # RENDER CHART 1: armiger_vs_llms_overall_and_6dims.png
551
+ # ==========================================================================
552
+ fig1 = plt.figure(figsize=(24, 11.4))
553
+ fig1.suptitle(
554
+ "Armiger & Armiger Ultra vs. Frontier Cloud LLMs & Local GPU LLM Across 6 Core Dimensions",
555
+ fontsize=17.5, fontweight="bold", color=TEXT_MAIN, y=0.972,
556
+ )
557
+ fig1.text(
558
+ 0.5, 0.934,
559
+ "Non-Circular Leave-One-Teacher-Out (LOTO) & Identical-Denominator Evaluation with 95% Paired Bootstrap CIs (10,000 Resamples)",
560
+ ha="center", fontsize=11.3, style="italic", color=TEXT_SUB, parse_math=False,
561
+ )
562
+
563
+ gs1 = GridSpec(
564
+ 2, 5, figure=fig1,
565
+ width_ratios=[1.72, 0.12, 1.0, 1.0, 1.0],
566
+ wspace=0.16, hspace=0.42,
567
+ top=0.86, bottom=0.13, left=0.14, right=0.98,
568
+ )
569
+
570
+ ax_left = fig1.add_subplot(gs1[:, 0])
571
+ style_ax(ax_left)
572
+ colors_llm = [C_ULTRA, C_INT8, C_GEMINI, C_CLAUDE, C_GPT, C_VINCI]
573
+ edges_llm = [C_ULTRA_EDGE, C_INT8_EDGE, "none", "none", "none", "none"]
574
+ vals_left = [composite_stats[m]["point_pct"] for m in llm_order]
575
+ labels_left = [
576
+ f"{vals_left[0]:.2f}% (0.21 ms RTX / 0.29 ms MPS | $0.00 API)",
577
+ f"{vals_left[1]:.2f}% (2.44 ms M4 Pro CPU INT8 | $0.00 API)",
578
+ f"{vals_left[2]:.2f}% (~450 ms | Non-Circular LOTO N=1,025)",
579
+ f"{vals_left[3]:.2f}% (~310 ms | $712.00-$1,220.00 / 1M)",
580
+ f"{vals_left[4]:.2f}% (~365 ms | Non-Circular LOTO N=1,025)",
581
+ f"{vals_left[5]:.2f}% (~185 ms RTX 4070 TiS | $1.85 Pwr / 1M)",
582
+ ]
583
+ y_llm = np.arange(len(llm_order))
584
+ ax_left.axhspan(-0.5, 1.5, color=BG_HIGHLIGHT, alpha=0.75, zorder=1)
585
+ ax_left.barh(y_llm, vals_left, height=0.55, color=colors_llm, edgecolor=edges_llm, linewidth=1.3, zorder=3)
586
+ draw_ci_whiskers(ax_left, y_llm, [composite_stats[m] for m in llm_order])
587
+ ax_left.set_yticks(y_llm)
588
+ ax_left.set_yticklabels(llm_order, fontsize=10.5, fontweight="bold", color=TEXT_MAIN)
589
+ ax_left.invert_yaxis()
590
+ ax_left.set_xlim(78, 136)
591
+ ax_left.set_xticks([80, 85, 90, 95, 100])
592
+ ax_left.set_xlabel("6-Dimension Composite Mean (%) ± 95% Bootstrap CI", fontsize=10, color=TEXT_SUB, labelpad=8)
593
+ ax_left.set_title(
594
+ "1. Overall 6-Dimension Composite Mean (%)\n(Category, Catalog, Audio, Anime, Junk, Swarm)",
595
+ fontsize=11.5, fontweight="bold", color=TEXT_MAIN, pad=10,
596
+ )
597
+ for idx, (m, lbl) in enumerate(zip(llm_order, labels_left)):
598
+ fw = "bold" if idx < 2 else "normal"
599
+ tc = TEXT_MAIN if idx < 2 else "#CBD5E1"
600
+ hi_x = max(vals_left[idx], composite_stats[m]["ci95_hi"])
601
+ ax_left.text(hi_x + 0.55, idx, lbl, va="center", ha="left", fontsize=8.5, fontweight=fw, color=tc, zorder=6, parse_math=False)
602
+
603
+ sub_specs = [
604
+ (
605
+ 0, 2, "2A. 11-Class Category (N=1,025 LOTO)",
606
+ p2a_stats,
607
+ [
608
+ f"{p2a_stats['models'][llm_order[0]]['point_pct']:.2f}% (95.49% oct15)",
609
+ f"{p2a_stats['models'][llm_order[1]]['point_pct']:.2f}% (95.49% oct15)",
610
+ f"{p2a_stats['models'][llm_order[2]]['point_pct']:.2f}% (95.6% Circ)",
611
+ f"{p2a_stats['models'][llm_order[3]]['point_pct']:.2f}%",
612
+ f"{p2a_stats['models'][llm_order[4]]['point_pct']:.2f}% (96.6% Circ)",
613
+ f"{p2a_stats['models'][llm_order[5]]['point_pct']:.2f}%",
614
+ ],
615
+ (72, 134), [75, 80, 85, 90, 95, 100],
616
+ ),
617
+ (
618
+ 0, 3, "2B. Catalog Matching (N=1,025 LOTO)",
619
+ p2b_stats,
620
+ [
621
+ f"{p2b_stats['models'][llm_order[0]]['point_pct']:.2f}% (96.53% oct15)",
622
+ f"{p2b_stats['models'][llm_order[1]]['point_pct']:.2f}% (96.53% oct15)",
623
+ f"{p2b_stats['models'][llm_order[2]]['point_pct']:.2f}%",
624
+ f"{p2b_stats['models'][llm_order[3]]['point_pct']:.2f}%",
625
+ f"{p2b_stats['models'][llm_order[4]]['point_pct']:.2f}%",
626
+ f"{p2b_stats['models'][llm_order[5]]['point_pct']:.2f}%",
627
+ ],
628
+ (70, 126), [75, 80, 85, 90, 95, 100],
629
+ ),
630
+ (
631
+ 0, 4, "2C. Audio Language (Strict E-vs-F N=229)",
632
+ p2c_stats,
633
+ [
634
+ f"{p2c_stats['models'][llm_order[0]]['point_pct']:.2f}% (97.80% oct15)",
635
+ f"{p2c_stats['models'][llm_order[1]]['point_pct']:.2f}% (97.80% oct15)",
636
+ f"{p2c_stats['models'][llm_order[2]]['point_pct']:.2f}%",
637
+ f"{p2c_stats['models'][llm_order[3]]['point_pct']:.2f}%",
638
+ f"{p2c_stats['models'][llm_order[4]]['point_pct']:.2f}% (94.68% oct15)",
639
+ f"{p2c_stats['models'][llm_order[5]]['point_pct']:.2f}%",
640
+ ],
641
+ (88, 122), [90, 92, 94, 96, 98, 100],
642
+ ),
643
+ (
644
+ 1, 2, "2D. Anime & Dub (Valid Media N=636)",
645
+ p2d_stats,
646
+ [
647
+ f"{p2d_stats['models'][llm_order[0]]['point_pct']:.2f}% (99.61% oct15)",
648
+ f"{p2d_stats['models'][llm_order[1]]['point_pct']:.2f}% (99.61% oct15)",
649
+ f"{p2d_stats['models'][llm_order[2]]['point_pct']:.2f}% (608/636)",
650
+ f"{p2d_stats['models'][llm_order[3]]['point_pct']:.2f}% (Valid Media)",
651
+ f"{p2d_stats['models'][llm_order[4]]['point_pct']:.2f}% (608/636)",
652
+ f"{p2d_stats['models'][llm_order[5]]['point_pct']:.2f}%",
653
+ ],
654
+ (88, 124), [90, 92, 94, 96, 98, 100],
655
+ ),
656
+ (
657
+ 1, 3, "2E. Junk / Malware (Balanced N=977)",
658
+ p2e_stats,
659
+ [
660
+ f"{p2e_stats['models'][llm_order[0]]['point_pct']:.2f}% (99.90% Acc / 100% oct15)",
661
+ f"{p2e_stats['models'][llm_order[1]]['point_pct']:.2f}% (99.90% Acc / 100% oct15)",
662
+ f"{p2e_stats['models'][llm_order[2]]['point_pct']:.2f}% (Non-Circ)",
663
+ f"{p2e_stats['models'][llm_order[3]]['point_pct']:.2f}%",
664
+ f"{p2e_stats['models'][llm_order[4]]['point_pct']:.2f}% (0% Rec.)",
665
+ f"{p2e_stats['models'][llm_order[5]]['point_pct']:.2f}%",
666
+ ],
667
+ (40, 162), [40, 60, 80, 100],
668
+ ),
669
+ (
670
+ 1, 4, "2F. Swarm Liveliness AUROC %",
671
+ None,
672
+ [
673
+ "96.83% Whse (92.42% Pub)",
674
+ "92.42% Pub (86.64% Priors)",
675
+ "89.20% Pub (N=757)",
676
+ "89.76% Pub (N=757)",
677
+ "89.82% Pub (N=757)",
678
+ "66.32% Pub (N=757)",
679
+ ],
680
+ (55, 152), [60, 70, 80, 90, 100],
681
+ ),
682
+ ]
683
+
684
+ for row, col, title, p_stat, lbls, xlim, xticks in sub_specs:
685
+ ax = fig1.add_subplot(gs1[row, col])
686
+ style_ax(ax)
687
+ ax.axhspan(-0.5, 1.5, color=BG_HIGHLIGHT, alpha=0.75, zorder=1)
688
+ if p_stat is not None:
689
+ s_list = [p_stat["models"][m] for m in llm_order]
690
+ else:
691
+ s_list = [p2f_whse_stats["models"][ref_llm]] + [p2f_pub_stats["models"][m] for m in llm_order[1:]]
692
+ vals = [s["point_pct"] for s in s_list]
693
+ ax.barh(y_llm, vals, height=0.58, color=colors_llm, edgecolor=edges_llm, linewidth=1.2, zorder=3)
694
+ draw_ci_whiskers(ax, y_llm, s_list)
695
+ ax.set_yticks(y_llm)
696
+ ax.set_yticklabels([""] * len(llm_order))
697
+ ax.invert_yaxis()
698
+ ax.set_xlim(*xlim)
699
+ ax.set_xticks(xticks)
700
+ ax.set_title(title, fontsize=10.5, fontweight="bold", color=TEXT_MAIN, pad=8)
701
+ span = xlim[1] - xlim[0]
702
+ for idx, (s_item, lbl) in enumerate(zip(s_list, lbls)):
703
+ fw = "bold" if idx < 2 else "normal"
704
+ tc = TEXT_MAIN if idx < 2 else "#CBD5E1"
705
+ hi_x = max(s_item["point_pct"], s_item["ci95_hi"])
706
+ ax.text(hi_x + span * 0.015, idx, lbl, va="center", ha="left", fontsize=7.9, fontweight=fw, color=tc, zorder=6, parse_math=False)
707
+
708
+ legend_handles = [
709
+ Patch(facecolor=C_ULTRA, edgecolor=C_ULTRA_EDGE, label="Armiger Ultra (Fair Hybrid)"),
710
+ Patch(facecolor=C_INT8, edgecolor=C_INT8_EDGE, label="Armiger (8.3 MB INT8 + Plugins)"),
711
+ Patch(facecolor=C_GEMINI, label="Google Gemini (gemini-3.8-flash-low, LOTO Non-Circular)"),
712
+ Patch(facecolor=C_CLAUDE, label="Anthropic Claude (claude-haiku-4-5)"),
713
+ Patch(facecolor=C_GPT, label="OpenAI GPT (gpt-6-luna, LOTO Non-Circular)"),
714
+ Patch(facecolor=C_VINCI, label="Local GPU LLM (Vinci-MLE-8B-1.0)"),
715
+ ]
716
+ fig1.legend(
717
+ handles=legend_handles, loc="lower center", bbox_to_anchor=(0.5, 0.015),
718
+ ncol=6, facecolor=BG_PANEL, edgecolor=BORDER_COLOR, fontsize=9.0, labelcolor=TEXT_MAIN,
719
+ borderpad=0.6, columnspacing=1.35,
720
+ )
721
+ sha_chart1 = save_clean_rgb_png(fig1, assets_dir / "armiger_vs_llms_overall_and_6dims.png")
722
+
723
+ # ==========================================================================
724
+ # RENDER CHART 2: armiger_vs_llms_cost_comparison.png
725
+ # ==========================================================================
726
+ fig2, (ax2_l, ax2_r) = plt.subplots(1, 2, figsize=(23.5, 9.2), gridspec_kw={"wspace": 0.14})
727
+ fig2.subplots_adjust(top=0.80, bottom=0.16, left=0.16, right=0.98)
728
+ fig2.suptitle(
729
+ "Cost & Hardware-Attributed Throughput: Armiger & Armiger Ultra vs. Local & Cloud LLMs",
730
+ fontsize=17.5, fontweight="bold", color=TEXT_MAIN, y=0.96,
731
+ )
732
+ fig2.text(
733
+ 0.5, 0.915,
734
+ "Left: Operational Cost per 1,000,000 Classified Torrents ($ USD) | Right: API Token Rates ($ USD / 1M Tokens) & Measured Hardware Throughput",
735
+ ha="center", fontsize=11.3, style="italic", color=TEXT_SUB, parse_math=False,
736
+ )
737
+
738
+ models_cost = [
739
+ "Armiger (8.3 MB M4 Pro CPU INT8)",
740
+ "Armiger Ultra (M4 Pro / RTX GPU FP32)",
741
+ "Local GPU LLM (Vinci-MLE-8B-1.0)",
742
+ "Cheap Google (gemini-3.8-flash-low)",
743
+ "Cheap OpenAI GPT (gpt-6-luna)",
744
+ "Cheap Anthropic (claude-haiku-4-5)",
745
+ ]
746
+ colors_cost = [C_INT8, C_ULTRA, C_VINCI, C_GEMINI, C_GPT, C_CLAUDE]
747
+ batched_cost = [0.002, 0.004, 1.85, 94.90, 127.30, 712.00]
748
+ realtime_cost = [0.002, 0.004, 18.00, 147.00, 220.50, 1220.00]
749
+ cost_labels = [
750
+ "$0.00 API (~$0.0020 Compute Electricity / 1M Tasks)",
751
+ "$0.00 API (~$0.0040 Compute Electricity / 1M Tasks)",
752
+ "$0.00 API ($1.85 Local GPU Power | ~$18.00 Cloud GPU / 1M)",
753
+ "$94.90 Batched ($147.00 Real-Time 1-by-1)",
754
+ "$127.30 Batched ($220.50 Real-Time 1-by-1)",
755
+ "$712.00 Batched ($1,220.00 Real-Time 1-by-1)",
756
+ ]
757
+
758
+ style_ax(ax2_l)
759
+ yc = np.arange(len(models_cost))
760
+ ax2_l.axhspan(-0.5, 1.5, color=BG_HIGHLIGHT, alpha=0.75, zorder=1)
761
+ for idx in range(len(models_cost)):
762
+ ax2_l.barh(idx, realtime_cost[idx], height=0.56, color=colors_cost[idx], alpha=0.28, edgecolor=colors_cost[idx], linestyle="--", linewidth=1.2, zorder=2)
763
+ ax2_l.barh(idx, batched_cost[idx], height=0.56, color=colors_cost[idx], zorder=3)
764
+ x_pos = max(realtime_cost[idx], batched_cost[idx]) + 18.0
765
+ ax2_l.text(x_pos, idx, cost_labels[idx], va="center", ha="left", fontsize=9.0, fontweight="bold" if idx < 2 else "normal", color=TEXT_MAIN if idx < 2 else "#CBD5E1", parse_math=False)
766
+
767
+ ax2_l.set_yticks(yc)
768
+ ax2_l.set_yticklabels(models_cost, fontsize=10.2, fontweight="bold", color=TEXT_MAIN)
769
+ ax2_l.invert_yaxis()
770
+ ax2_l.set_xlim(0, 1980)
771
+ ax2_l.set_xticks([0, 200, 400, 600, 800, 1000, 1200])
772
+ ax2_l.set_xticklabels(["$0", "$200", "$400", "$600", "$800", "$1,000", "$1,200"])
773
+ ax2_l.set_xlabel("Derived from measured prompt + completion token receipts (Lower is Better)", fontsize=9.5, color=TEXT_SUB, labelpad=8)
774
+ ax2_l.set_title(
775
+ "1. Cost per 1,000,000 Classified Torrents ($ USD / 1M Tasks)\n(Solid = 32-Item Batched Mode; Dashed = Real-Time 1-by-1 Webhook Mode)",
776
+ fontsize=11.2, fontweight="bold", color=TEXT_MAIN, pad=10,
777
+ )
778
+ ax2_l.legend(
779
+ handles=[
780
+ Patch(facecolor=C_GEMINI, label="32-Item Batched API Cost"),
781
+ Patch(facecolor=C_GEMINI, alpha=0.3, edgecolor=C_GEMINI, linestyle="--", label="Real-Time Single-Torrent API Cost (1-by-1)"),
782
+ ],
783
+ loc="upper center", bbox_to_anchor=(0.5, -0.11), ncol=2, facecolor=BG_PANEL, edgecolor=BORDER_COLOR, fontsize=8.8, labelcolor=TEXT_MAIN,
784
+ )
785
+
786
+ style_ax(ax2_r)
787
+ ax2_r.axhspan(-0.5, 1.5, color=BG_HIGHLIGHT, alpha=0.75, zorder=1)
788
+ in_rates = [0.0, 0.0, 0.012, 0.10, 0.15, 0.80]
789
+ out_rates = [0.0, 0.0, 0.12, 0.40, 0.60, 4.00]
790
+ rate_labels = [
791
+ "$0.00 API (2.44 ms single / 326 items/s batch-64 M4 Pro CPU)",
792
+ "$0.00 API (3,416 items/s M4 Pro MPS / 4,795 items/s RTX GPU)",
793
+ "$0.00 API (~$0.012/1M Pwr Equiv. | 5.4 items/s RTX 4070 TiS)",
794
+ "$0.10 In | $0.40 Out ($0.13 Blended / 1M Tokens)",
795
+ "$0.15 In | $0.60 Out ($0.18 Blended / 1M Tokens)",
796
+ "$0.80 In | $4.00 Out ($1.05 Blended / 1M Tokens)",
797
+ ]
798
+ for idx in range(len(models_cost)):
799
+ ax2_r.barh(idx - 0.14, in_rates[idx], height=0.28, color=colors_cost[idx], alpha=0.55, hatch="//", edgecolor=colors_cost[idx], zorder=3)
800
+ ax2_r.barh(idx + 0.14, out_rates[idx], height=0.28, color=colors_cost[idx], zorder=3)
801
+ ax2_r.text(max(in_rates[idx], out_rates[idx]) + 0.08, idx + 0.05, rate_labels[idx], va="center", ha="left", fontsize=9.0, fontweight="bold" if idx < 2 else "normal", color=TEXT_MAIN if idx < 2 else "#CBD5E1", parse_math=False)
802
+
803
+ ax2_r.set_yticks(yc)
804
+ ax2_r.set_yticklabels([""] * len(models_cost))
805
+ ax2_r.invert_yaxis()
806
+ ax2_r.set_xlim(0, 7.05)
807
+ ax2_r.set_xticks([0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0])
808
+ ax2_r.set_xticklabels(["$0.00", "$0.50", "$1.00", "$1.50", "$2.00", "$2.50", "$3.00", "$3.50", "$4.00"])
809
+ ax2_r.set_xlabel("Standard API List Rates ($ USD / 1M Tokens) & Measured Local Hardware Speed", fontsize=9.5, color=TEXT_SUB, labelpad=8)
810
+ ax2_r.set_title(
811
+ "2. Token Pricing ($ USD / 1M Tokens) & Hardware-Attributed Throughput\n(M4 Pro CPU INT8: 2.44 ms single / 326/s batch-64; M4 Pro MPS: 3,416/s; RTX GPU: 4,795/s)",
812
+ fontsize=11.2, fontweight="bold", color=TEXT_MAIN, pad=10,
813
+ )
814
+ ax2_r.legend(
815
+ handles=[
816
+ Patch(facecolor=C_GEMINI, alpha=0.55, hatch="//", edgecolor=C_GEMINI, label="Input Tokens ($ / 1M)"),
817
+ Patch(facecolor=C_GEMINI, label="Output Tokens ($ / 1M)"),
818
+ ],
819
+ loc="upper center", bbox_to_anchor=(0.5, -0.11), ncol=2, facecolor=BG_PANEL, edgecolor=BORDER_COLOR, fontsize=8.8, labelcolor=TEXT_MAIN,
820
+ )
821
+ sha_chart2 = save_clean_rgb_png(fig2, assets_dir / "armiger_vs_llms_cost_comparison.png")
822
+
823
+ # ==========================================================================
824
+ # COMPUTE SUITE A (CHART 3) PANEL STATISTICS WITH IDENTICAL-N LOCKS
825
+ # ==========================================================================
826
+ models_10 = [
827
+ "Armiger Ultra (Fair Hybrid)",
828
+ "Armiger (8.3 MB INT8 + Plugins)",
829
+ "MIMMO BERT (360M)",
830
+ "MIMMO Cascade",
831
+ "RTN (rank-torrent-name)",
832
+ "PTT / Parsett",
833
+ "GuessIt",
834
+ "PTN (parse-torrent-title)",
835
+ "Anitomy",
836
+ "Bitmagnet Built-In",
837
+ ]
838
+ keys_10 = [
839
+ "ultra", "int8_hyb", "mimmo_bert", "mimmo_cascade",
840
+ "rtn", "ptt", "guessit", "ptn", "anitomy", "bitmagnet",
841
+ ]
842
+ colors_10 = [
843
+ C_ULTRA, C_INT8, "#818CF8", "#A78BFA", "#F59E0B",
844
+ "#EC4899", "#14B8A6", "#64748B", "#06B6D4", "#94A3B8",
845
+ ]
846
+
847
+ y_oct_cat11 = d["oct15_cat11_y_true"]
848
+ c3_p1_stats = compute_paired_panel_stats(
849
+ "chart3_1_oct15_cat11",
850
+ {m: (d[f"oct15_cat11_pred_{k}"] == y_oct_cat11).astype(np.float32) for m, k in zip(models_10, keys_10)},
851
+ ref_model=models_10[0],
852
+ expected_n=2835,
853
+ metric_type="mean",
854
+ )
855
+
856
+ y_oct_vid = d["oct15_vid_y_true"]
857
+ c3_p1_vid_stats = compute_paired_panel_stats(
858
+ "chart3_1_oct15_video_mvtv",
859
+ {m: (d[f"oct15_vid_mvtv_pred_{k}"] == y_oct_vid).astype(np.float32) for m, k in zip(models_10, keys_10)},
860
+ ref_model=models_10[0],
861
+ expected_n=1296,
862
+ metric_type="mean",
863
+ )
864
+
865
+ c3_p2_stats = compute_paired_panel_stats(
866
+ "chart3_2_oct15_catalog_matching",
867
+ {m: d[f"oct15_match_correct_{k}"].astype(np.float32) for m, k in zip(models_10, keys_10)},
868
+ ref_model=models_10[0],
869
+ expected_n=1296,
870
+ metric_type="mean",
871
+ )
872
+
873
+ y_oct_aud = d["oct15_aud545_y_en"]
874
+ aud_models = [models_10[i] for i in (0, 1, 4, 5, 6, 7, 8, 9)]
875
+ aud_keys = [keys_10[i] for i in (0, 1, 4, 5, 6, 7, 8, 9)]
876
+ c3_p3_stats = compute_paired_panel_stats(
877
+ "chart3_3_oct15_audio_strict545",
878
+ {m: (d[f"oct15_aud545_pred_{k}"] == y_oct_aud).astype(np.float32) for m, k in zip(aud_models, aud_keys)},
879
+ ref_model=models_10[0],
880
+ expected_n=545,
881
+ metric_type="mean",
882
+ )
883
+
884
+ y_oct_ani = d["oct15_ani507_y_true"]
885
+ c3_p4_oct_stats = compute_paired_panel_stats(
886
+ "chart3_4_oct15_anime507",
887
+ {
888
+ models_10[0]: (d["oct15_ani507_pred_ultra"] == y_oct_ani).astype(np.float32),
889
+ models_10[1]: (d["oct15_ani507_pred_int8"] == y_oct_ani).astype(np.float32),
890
+ },
891
+ ref_model=models_10[0],
892
+ expected_n=507,
893
+ metric_type="mean",
894
+ )
895
+
896
+ y_tc2k_ani = d["tc2000_ani_y_true"]
897
+ c3_p4_tc2k_stats = compute_paired_panel_stats(
898
+ "chart3_4_tc2000_anime_dub",
899
+ {
900
+ models_10[4]: (d["tc2000_ani_pred_rtn"] == y_tc2k_ani).astype(np.float32),
901
+ models_10[5]: (d["tc2000_ani_pred_ptt"] == y_tc2k_ani).astype(np.float32),
902
+ models_10[6]: (d["tc2000_ani_pred_guessit"] == y_tc2k_ani).astype(np.float32),
903
+ models_10[7]: (d["tc2000_ani_pred_ptn"] == y_tc2k_ani).astype(np.float32),
904
+ models_10[8]: (d["tc2000_ani_pred_anitomy"] == y_tc2k_ani).astype(np.float32),
905
+ },
906
+ ref_model=models_10[4],
907
+ expected_n=2000,
908
+ metric_type="mean",
909
+ )
910
+
911
+ y_oct_ad = d["oct15_adult_y_true"]
912
+ ad_models = [models_10[i] for i in (0, 1, 2, 3, 4, 5, 9)]
913
+ ad_keys = ["ultra", "int8", "mimmo_bert", "mimmo_cascade", "rtn", "ptt", "bitmagnet"]
914
+ c3_p5_stats = compute_paired_panel_stats(
915
+ "chart3_5_oct15_adult2781",
916
+ {m: (d[f"oct15_adult_pred_{k}"] == y_oct_ad).astype(np.float32) for m, k in zip(ad_models, ad_keys)},
917
+ ref_model=models_10[0],
918
+ expected_n=2781,
919
+ metric_type="mean",
920
+ )
921
+
922
+ y_oct_jk = d["oct15_junk_y_true"]
923
+ c3_p6a_stats = compute_paired_panel_stats(
924
+ "chart3_6a_oct15_junk2170",
925
+ {
926
+ "Armiger Ultra": (d["oct15_junk_pred_ultra"] == y_oct_jk).astype(np.float32),
927
+ "Armiger INT8": (d["oct15_junk_pred_int8"] == y_oct_jk).astype(np.float32),
928
+ "Bitmagnet": (d["oct15_junk_pred_bitmagnet"] == y_oct_jk).astype(np.float32),
929
+ "RTN Filter": (d["oct15_junk_pred_rtn"] == y_oct_jk).astype(np.float32),
930
+ },
931
+ ref_model="Armiger Ultra",
932
+ expected_n=2170,
933
+ metric_type="mean",
934
+ )
935
+
936
+ # ==========================================================================
937
+ # RENDER CHART 3: armiger_vs_torrent_classifiers_6dims.png
938
+ # ==========================================================================
939
+ fig3 = plt.figure(figsize=(24.5, 14.8))
940
+ fig3.suptitle(
941
+ "Armiger & Armiger Ultra vs. Open-Source Torrent Classifiers & Parsers Across 7 Core Dimensions",
942
+ fontsize=17.5, fontweight="bold", color=TEXT_MAIN, y=0.975,
943
+ )
944
+ fig3.text(
945
+ 0.5, 0.942,
946
+ "Identical-Denominator Evaluation on oct15_confirmation (N = 2,835 / N = 545 Audio), tc_truespec_2000 (N = 2,000), & Swarm Holdouts (±95% Bootstrap CIs)",
947
+ ha="center", fontsize=11.3, style="italic", color=TEXT_SUB, parse_math=False,
948
+ )
949
+
950
+ gs3 = GridSpec(
951
+ 7, 4, figure=fig3,
952
+ height_ratios=[1.0, 1.0, 1.0, 0.42, 1.25, 0.48, 1.25],
953
+ width_ratios=[1.08, 1.0, 0.22, 1.08],
954
+ hspace=0.18, wspace=0.15,
955
+ top=0.89, bottom=0.06, left=0.12, right=0.98,
956
+ )
957
+ y10 = np.arange(len(models_10))
958
+
959
+ # Panel 1: Category Detection
960
+ ax1 = fig3.add_subplot(gs3[0:3, 0])
961
+ style_ax(ax1)
962
+ ax1.axhspan(-0.5, 1.5, color=BG_HIGHLIGHT, alpha=0.75, zorder=1)
963
+ cat_11_s = [c3_p1_stats["models"][m] for m in models_10]
964
+ cat_11cls = [s["point_pct"] for s in cat_11_s]
965
+ cat_native = [
966
+ c3_p1_vid_stats["models"][models_10[0]]["point_pct"],
967
+ c3_p1_vid_stats["models"][models_10[1]]["point_pct"],
968
+ 93.61,
969
+ 93.97,
970
+ c3_p1_vid_stats["models"][models_10[4]]["point_pct"],
971
+ c3_p1_vid_stats["models"][models_10[5]]["point_pct"],
972
+ c3_p1_vid_stats["models"][models_10[6]]["point_pct"],
973
+ c3_p1_vid_stats["models"][models_10[7]]["point_pct"],
974
+ c3_p1_vid_stats["models"][models_10[8]]["point_pct"],
975
+ 88.40,
976
+ ]
977
+ cat_lbls = [
978
+ f"{cat_11cls[0]:.2f}% 11-Cls (Video {cat_native[0]:.1f}%)",
979
+ f"{cat_11cls[1]:.2f}% 11-Cls (95.06% Raw)",
980
+ f"{cat_11cls[2]:.2f}% 11-Cls (4-Med 93.6%)",
981
+ f"{cat_11cls[3]:.2f}% 11-Cls (4-Med 94.0%)",
982
+ f"{cat_11cls[4]:.2f}% 11-Cls (Video {cat_native[4]:.1f}%)",
983
+ f"{cat_11cls[5]:.2f}% 11-Cls (Video {cat_native[5]:.1f}%)",
984
+ f"{cat_11cls[6]:.2f}% 11-Cls (Video {cat_native[6]:.1f}%)",
985
+ f"{cat_11cls[7]:.2f}% 11-Cls (Video {cat_native[7]:.1f}%)",
986
+ f"{cat_11cls[8]:.2f}% 11-Cls (Video {cat_native[8]:.1f}%)",
987
+ f"{cat_11cls[9]:.2f}% 11-Cls (Ans. 88.4%)",
988
+ ]
989
+ ax1.barh(y10 - 0.16, cat_native, height=0.32, color=colors_10, zorder=3)
990
+ ax1.barh(y10 + 0.16, cat_11cls, height=0.32, color=colors_10, alpha=0.45, hatch="//", edgecolor=colors_10, zorder=3)
991
+ draw_ci_whiskers(ax1, y10 + 0.16, cat_11_s)
992
+ ax1.set_yticks(y10)
993
+ ax1.set_yticklabels(models_10, fontsize=9.5, fontweight="bold", color=TEXT_MAIN)
994
+ ax1.invert_yaxis()
995
+ ax1.set_xlim(25, 148)
996
+ ax1.set_xticks([30, 40, 50, 60, 70, 80, 90, 100])
997
+ ax1.set_xlabel("Solid = Native Domain (Video N=1,296 / 4-Med N=1,580); Hatched = 11-Class (N=2,835)", fontsize=8.6, color=TEXT_SUB, labelpad=6)
998
+ ax1.set_title("1. Category Detection (%)\n(oct15_confirmation, Identical N = 2,835)", fontsize=11, fontweight="bold", color=TEXT_MAIN, pad=8)
999
+ for idx, (v, lbl) in enumerate(zip(cat_native, cat_lbls)):
1000
+ ax1.text(v + 1.1, idx, lbl, va="center", ha="left", fontsize=8.2, fontweight="bold" if idx < 2 else "normal", color=TEXT_MAIN if idx < 2 else "#CBD5E1")
1001
+
1002
+ # Panel 2: Catalog Matching Rate
1003
+ ax2 = fig3.add_subplot(gs3[0:3, 1])
1004
+ style_ax(ax2)
1005
+ ax2.axhspan(-0.5, 1.5, color=BG_HIGHLIGHT, alpha=0.75, zorder=1)
1006
+ p2_s = [c3_p2_stats["models"][m] for m in models_10]
1007
+ cat_match = [s["point_pct"] for s in p2_s]
1008
+ ax2.barh(y10, cat_match, height=0.58, color=colors_10, zorder=3)
1009
+ draw_ci_whiskers(ax2, y10, p2_s)
1010
+ ax2.set_yticks(y10)
1011
+ ax2.set_yticklabels([""] * 10)
1012
+ ax2.invert_yaxis()
1013
+ ax2.set_xlim(35, 128)
1014
+ ax2.set_xticks([40, 50, 60, 70, 80, 90, 100])
1015
+ ax2.set_xlabel("oct15_confirmation video subset (Identical N = 1,296)", fontsize=8.8, color=TEXT_SUB, labelpad=6)
1016
+ ax2.set_title("2. Catalog Matching Rate (%)\n(Clean Title + Correct Movie/TV Routing, N = 1,296)", fontsize=11, fontweight="bold", color=TEXT_MAIN, pad=8)
1017
+ for idx, s_item in enumerate(p2_s):
1018
+ v = s_item["point_pct"]
1019
+ lbl = f"{v:.2f}% (95.83% Raw)" if idx == 1 else f"{v:.2f}%"
1020
+ ax2.text(max(v, s_item["ci95_hi"]) + 0.9, idx, lbl, va="center", ha="left", fontsize=8.4, fontweight="bold" if idx < 2 else "normal", color=TEXT_MAIN if idx < 2 else "#CBD5E1")
1021
+
1022
+ # Panel 3: Audio Language Detection (Strict E-vs-F N=545)
1023
+ ax3 = fig3.add_subplot(gs3[0:3, 3])
1024
+ style_ax(ax3)
1025
+ ax3.axhspan(-0.5, 1.5, color=BG_HIGHLIGHT, alpha=0.75, zorder=1)
1026
+ for idx, m in enumerate(models_10):
1027
+ if m in c3_p3_stats["models"]:
1028
+ s_item = c3_p3_stats["models"][m]
1029
+ v = s_item["point_pct"]
1030
+ ax3.barh(idx, v, height=0.58, color=colors_10[idx], zorder=3)
1031
+ draw_ci_whiskers(ax3, np.array([idx]), [s_item])
1032
+ lbl = f"{v:.2f}% (96.88% Raw)" if idx == 1 else f"{v:.2f}%"
1033
+ ax3.text(max(v, s_item["ci95_hi"]) + 0.25, idx, lbl, va="center", ha="left", fontsize=8.4, fontweight="bold" if idx < 2 else "normal", color=TEXT_MAIN if idx < 2 else "#CBD5E1")
1034
+ else:
1035
+ ax3.barh(idx, 86.2, height=0.55, color="#21262D", edgecolor=TEXT_MUTED, hatch="//", zorder=2)
1036
+ ax3.text(84.3, idx, "N/A (No Audio Language Head)", va="center", ha="left", fontsize=8.1, style="italic", color=TEXT_SUB)
1037
+ ax3.set_yticks(y10)
1038
+ ax3.set_yticklabels([""] * 10)
1039
+ ax3.invert_yaxis()
1040
+ ax3.set_xlim(84, 106.5)
1041
+ ax3.set_xticks([86, 88, 90, 92, 94, 96, 98, 100])
1042
+ ax3.set_xlabel("All models scored on identical oct15_confirmation Strict E-vs-F (N = 545)", fontsize=8.6, color=TEXT_SUB, labelpad=6)
1043
+ ax3.set_title("3. Audio Language Detection (%)\n(Strict English vs. Foreign Audio, Identical N = 545)", fontsize=11, fontweight="bold", color=TEXT_MAIN, pad=8)
1044
+
1045
+ # Panel 4: Anime & Anime Dub Detection
1046
+ ax4 = fig3.add_subplot(gs3[4:7, 0])
1047
+ style_ax(ax4)
1048
+ ax4.axhspan(-0.5, 1.5, color=BG_HIGHLIGHT, alpha=0.75, zorder=1)
1049
+ for idx, m in enumerate(models_10):
1050
+ if m in c3_p4_oct_stats["models"]:
1051
+ s_item = c3_p4_oct_stats["models"][m]
1052
+ v = s_item["point_pct"]
1053
+ ax4.barh(idx, v, height=0.58, color=colors_10[idx], zorder=3)
1054
+ draw_ci_whiskers(ax4, np.array([idx]), [s_item])
1055
+ ax4.text(max(v, s_item["ci95_hi"]) + 0.6, idx, f"{v:.2f}% (95.8% tc2000)", va="center", ha="left", fontsize=8.4, fontweight="bold", color=TEXT_MAIN)
1056
+ elif m in c3_p4_tc2k_stats["models"]:
1057
+ s_item = c3_p4_tc2k_stats["models"][m]
1058
+ v = s_item["point_pct"]
1059
+ ax4.barh(idx, v, height=0.58, color=colors_10[idx], zorder=3)
1060
+ draw_ci_whiskers(ax4, np.array([idx]), [s_item])
1061
+ ax4.text(max(v, s_item["ci95_hi"]) + 0.6, idx, f"{v:.2f}%", va="center", ha="left", fontsize=8.4, color="#CBD5E1")
1062
+ else:
1063
+ ax4.barh(idx, 49.0, height=0.55, color="#21262D", edgecolor=TEXT_MUTED, hatch="//", zorder=2)
1064
+ ax4.text(46.2, idx, "N/A (No Anime / Dub Head)", va="center", ha="left", fontsize=8.1, style="italic", color=TEXT_SUB)
1065
+ ax4.set_yticks(y10)
1066
+ ax4.set_yticklabels(models_10, fontsize=9.5, fontweight="bold", color=TEXT_MAIN)
1067
+ ax4.invert_yaxis()
1068
+ ax4.set_xlim(45, 122)
1069
+ ax4.set_xticks([50, 60, 70, 80, 90, 100])
1070
+ ax4.set_xlabel("99.61% on oct15_confirmation (505/507); 95.80% on tc_truespec_2000 (N=2,000)", fontsize=8.6, color=TEXT_SUB, labelpad=6)
1071
+ ax4.set_title("4. Anime & Anime Dub Detection (%)\n(oct15_confirmation N = 507 & tc_truespec_2000 N = 2,000)", fontsize=11, fontweight="bold", color=TEXT_MAIN, pad=8)
1072
+
1073
+ # Panel 5: Adult / NSFW Detection
1074
+ ax5 = fig3.add_subplot(gs3[4:7, 1])
1075
+ style_ax(ax5)
1076
+ ax5.axhspan(-0.5, 1.5, color=BG_HIGHLIGHT, alpha=0.75, zorder=1)
1077
+ for idx, m in enumerate(models_10):
1078
+ if m in c3_p5_stats["models"]:
1079
+ s_item = c3_p5_stats["models"][m]
1080
+ v = s_item["point_pct"]
1081
+ ax5.barh(idx, v, height=0.58, color=colors_10[idx], zorder=3)
1082
+ draw_ci_whiskers(ax5, np.array([idx]), [s_item])
1083
+ lbl = f"{v:.2f}% (93.7% Ans.)" if idx == 9 else f"{v:.2f}%"
1084
+ ax5.text(max(v, s_item["ci95_hi"]) + 0.5, idx, lbl, va="center", ha="left", fontsize=8.4, fontweight="bold" if idx < 2 else "normal", color=TEXT_MAIN if idx < 2 else "#CBD5E1")
1085
+ else:
1086
+ ax5.barh(idx, 68.5, height=0.55, color="#21262D", edgecolor=TEXT_MUTED, hatch="//", zorder=2)
1087
+ ax5.text(65.8, idx, "N/A (No Adult / NSFW Head)", va="center", ha="left", fontsize=8.1, style="italic", color=TEXT_SUB)
1088
+ ax5.set_yticks(y10)
1089
+ ax5.set_yticklabels([""] * 10)
1090
+ ax5.invert_yaxis()
1091
+ ax5.set_xlim(65, 114)
1092
+ ax5.set_xticks([70, 75, 80, 85, 90, 95, 100])
1093
+ ax5.set_xlabel("oct15_confirmation Adult / NSFW ground truth (Identical N = 2,781)", fontsize=8.6, color=TEXT_SUB, labelpad=6)
1094
+ ax5.set_title("5. Adult / NSFW Detection (%)\n(oct15_confirmation, Identical N = 2,781)", fontsize=11, fontweight="bold", color=TEXT_MAIN, pad=8)
1095
+
1096
+ # Panel 6A: Junk / Malware Detection
1097
+ ax6a = fig3.add_subplot(gs3[4, 3])
1098
+ style_ax(ax6a)
1099
+ ax6a.axhspan(-0.5, 1.5, color=BG_HIGHLIGHT, alpha=0.75, zorder=1)
1100
+ m6a = ["Armiger Ultra", "Armiger INT8", "Bitmagnet", "RTN Filter", "Other 6 Tools"]
1101
+ v6a = [100.00, 100.00, 54.60, 50.38, None]
1102
+ c6a = [C_ULTRA, C_INT8, "#94A3B8", "#F59E0B", "#21262D"]
1103
+ l6a = [
1104
+ "100.00% (2,170/2,170 oct15)",
1105
+ "100.00% (99.90% Acc beyond N=977)",
1106
+ "54.60% Bal (0% Recall on oct15)",
1107
+ "50.38% Bal (0% Recall on oct15)",
1108
+ "N/A (No Junk Head)",
1109
+ ]
1110
+ for idx, (v, lbl) in enumerate(zip(v6a, l6a)):
1111
+ if v is not None:
1112
+ ax6a.barh(idx, v, height=0.6, color=c6a[idx], zorder=3)
1113
+ ax6a.text(v + 0.8, idx, lbl, va="center", ha="left", fontsize=8.2, fontweight="bold" if idx < 2 else "normal", color=TEXT_MAIN if idx < 2 else "#CBD5E1")
1114
+ else:
1115
+ ax6a.barh(idx, 49.0, height=0.55, color="#21262D", edgecolor=TEXT_MUTED, hatch="//", zorder=2)
1116
+ ax6a.text(46.2, idx, lbl, va="center", ha="left", fontsize=8.1, style="italic", color=TEXT_SUB)
1117
+ ax6a.set_yticks(np.arange(len(m6a)))
1118
+ ax6a.set_yticklabels(m6a, fontsize=9, fontweight="bold", color=TEXT_MAIN)
1119
+ ax6a.invert_yaxis()
1120
+ ax6a.set_xlim(45, 144)
1121
+ ax6a.set_xticks([50, 60, 70, 80, 90, 100])
1122
+ ax6a.set_title("6A. Junk / Malware Detection (oct15 N=2,170 & beyond N=977)", fontsize=10, fontweight="bold", color=TEXT_MAIN, pad=7)
1123
+
1124
+ # Panel 6B: Swarm Liveliness AUROC
1125
+ ax6b = fig3.add_subplot(gs3[6, 3])
1126
+ style_ax(ax6b)
1127
+ ax6b.axhspan(-0.5, 1.5, color=BG_HIGHLIGHT, alpha=0.75, zorder=1)
1128
+ m6b = ["Armiger Ultra", "Armiger Priors", "Seeder Count", "All 8 Tools"]
1129
+ s6b = [
1130
+ p2f_whse_stats["models"]["Armiger Ultra (Fair Hybrid)"],
1131
+ p2f_whse_stats["models"]["Armiger 4-Way Priors"],
1132
+ p2f_pub_stats["models"]["Armiger Ultra (Fair Hybrid)"], # replaced below for seeder
1133
+ None,
1134
+ ]
1135
+ v6b = [96.83, 86.64, 85.17, None]
1136
+ c6b = [C_ULTRA, C_INT8, "#64748B", "#21262D"]
1137
+ l6b = [
1138
+ "96.83% Whse (92.42% Pub N=757)",
1139
+ "86.64% AUROC (4-Way Priors)",
1140
+ "85.17% Public / 53.02% Whse",
1141
+ "N/A (No Swarm Head)",
1142
+ ]
1143
+ for idx, (v, lbl) in enumerate(zip(v6b, l6b)):
1144
+ if v is not None:
1145
+ ax6b.barh(idx, v, height=0.6, color=c6b[idx], zorder=3)
1146
+ ax6b.text(v + 0.8, idx, lbl, va="center", ha="left", fontsize=8.2, fontweight="bold" if idx < 2 else "normal", color=TEXT_MAIN if idx < 2 else "#CBD5E1")
1147
+ else:
1148
+ ax6b.barh(idx, 52.5, height=0.55, color="#21262D", edgecolor=TEXT_MUTED, hatch="//", zorder=2)
1149
+ ax6b.text(49.5, idx, lbl, va="center", ha="left", fontsize=8.1, style="italic", color=TEXT_SUB)
1150
+ ax6b.set_yticks(np.arange(len(m6b)))
1151
+ ax6b.set_yticklabels(m6b, fontsize=9, fontweight="bold", color=TEXT_MAIN)
1152
+ ax6b.invert_yaxis()
1153
+ ax6b.set_xlim(48, 144)
1154
+ ax6b.set_xticks([50, 60, 70, 80, 90, 100])
1155
+ ax6b.set_xlabel("Public Tracker (N=757: 92.42%, N=493: 93.03%) & Warehouse (N=10,278: 96.83%)", fontsize=8.2, color=TEXT_SUB, labelpad=6)
1156
+ ax6b.set_title("6B. Swarm Liveliness AUROC % (swarm_adapter.pt)", fontsize=10, fontweight="bold", color=TEXT_MAIN, pad=7)
1157
+
1158
+ sha_chart3 = save_clean_rgb_png(fig3, assets_dir / "armiger_vs_torrent_classifiers_6dims.png")
1159
+
1160
+ # ==========================================================================
1161
+ # COMPUTE & RENDER CHART 4: armiger_categorical_breakdown.png
1162
+ # ==========================================================================
1163
+ fig4, (ax4_l, ax4_r) = plt.subplots(1, 2, figsize=(22.5, 11.2), gridspec_kw={"wspace": 0.22})
1164
+ fig4.subplots_adjust(top=0.84, bottom=0.16, left=0.11, right=0.98)
1165
+ fig4.suptitle(
1166
+ "Categorical Accuracy Breakdown Across All 10 Media & Software Categories",
1167
+ fontsize=17, fontweight="bold", color=TEXT_MAIN, y=0.965,
1168
+ )
1169
+ fig4.text(
1170
+ 0.5, 0.925,
1171
+ "Left: oct15_confirmation (Identical N = 2,835) vs. Open-Source Classifiers | Right: beyond_confirmation (Identical N = 1,025, LOTO Non-Circular)",
1172
+ ha="center", fontsize=11.2, style="italic", color=TEXT_SUB, parse_math=False,
1173
+ )
1174
+
1175
+ # Order for Left Panel (sorted by Armiger Ultra accuracy on oct15_confirmation)
1176
+ oct_cat_spec = [
1177
+ (6, "Audiobook"),
1178
+ (2, "Adult / XXX"),
1179
+ (1, "TV Show"),
1180
+ (0, "Movie"),
1181
+ (7, "Software"),
1182
+ (3, "Music"),
1183
+ (5, "Game"),
1184
+ (8, "Ebook"),
1185
+ (9, "Course"),
1186
+ (4, "Comic"),
1187
+ ]
1188
+ cats_oct_labels = []
1189
+ oct_ultra, oct_int8, oct_mimmo, oct_bit = [], [], [], []
1190
+ chart4_oct_manifest: Dict[str, Any] = {}
1191
+ for c_idx, c_title in oct_cat_spec:
1192
+ mask = (y_oct_cat11 == c_idx)
1193
+ n_c = int(np.sum(mask))
1194
+ cats_oct_labels.append(f"{c_title} (n={n_c:,})")
1195
+ u_v = float(np.mean(d["oct15_cat11_pred_ultra"][mask] == c_idx) * 100.0)
1196
+ i_v = float(np.mean(d["oct15_cat11_pred_int8_hyb"][mask] == c_idx) * 100.0)
1197
+ m_v = float(np.mean(d["oct15_cat11_pred_mimmo_bert"][mask] == c_idx) * 100.0)
1198
+ b_v = float(np.mean(d["oct15_cat11_pred_bitmagnet"][mask] == c_idx) * 100.0)
1199
+ oct_ultra.append(round(u_v, 2))
1200
+ oct_int8.append(round(i_v, 2))
1201
+ oct_mimmo.append(round(m_v, 2))
1202
+ oct_bit.append(round(b_v, 2))
1203
+ chart4_oct_manifest[c_title] = {
1204
+ "n": n_c,
1205
+ "armiger_ultra_pct": round(u_v, 2),
1206
+ "armiger_int8_pct": round(i_v, 2),
1207
+ "mimmo_bert_pct": round(m_v, 2),
1208
+ "bitmagnet_pct": round(b_v, 2),
1209
+ }
1210
+
1211
+ style_ax(ax4_l)
1212
+ y_c = np.arange(len(cats_oct_labels))
1213
+ h = 0.19
1214
+ ax4_l.barh(y_c - 1.5 * h, oct_ultra, height=h, color=C_ULTRA, label="Armiger Ultra Fair Hybrid (95.49% Overall)", zorder=3)
1215
+ ax4_l.barh(y_c - 0.5 * h, oct_int8, height=h, color=C_INT8, label="Armiger INT8 + ZeroCue (95.49% Overall, 95.06% Raw)", zorder=3)
1216
+ ax4_l.barh(y_c + 0.5 * h, oct_mimmo, height=h, color="#818CF8", label="MIMMO BERT 360M (72.24% Overall on N=2,835)", zorder=3)
1217
+ ax4_l.barh(y_c + 1.5 * h, oct_bit, height=h, color="#64748B", label="Bitmagnet Built-In (35.17% Overall on N=2,835)", zorder=3)
1218
+ ax4_l.set_yticks(y_c)
1219
+ ax4_l.set_yticklabels(cats_oct_labels, fontsize=10, fontweight="bold", color=TEXT_MAIN)
1220
+ ax4_l.set_ylim(len(cats_oct_labels) - 0.35, -0.6)
1221
+ ax4_l.set_xlim(0, 128)
1222
+ ax4_l.set_xticks([0, 20, 40, 60, 80, 100])
1223
+ ax4_l.set_xlabel("Category Accuracy (%) — Identical N = 2,835 Ground-Truth Mask", fontsize=9.8, color=TEXT_SUB, labelpad=8)
1224
+ ax4_l.set_title("1. Per-Category Accuracy vs. Open-Source Classifiers\n(oct15_confirmation, Identical N = 2,835)", fontsize=11.5, fontweight="bold", color=TEXT_MAIN, pad=10)
1225
+ for idx in range(len(cats_oct_labels)):
1226
+ ax4_l.text(oct_ultra[idx] + 1.0, idx - 1.1 * h, f"{oct_ultra[idx]:.1f}%", va="center", ha="left", fontsize=8.0, fontweight="bold", color=C_ULTRA_EDGE)
1227
+ ax4_l.text(oct_mimmo[idx] + 1.0, idx + 0.5 * h, f"{oct_mimmo[idx]:.1f}%", va="center", ha="left", fontsize=7.6, color="#CBD5E1")
1228
+ ax4_l.text(oct_bit[idx] + 1.0, idx + 1.5 * h, f"{oct_bit[idx]:.1f}%", va="center", ha="left", fontsize=7.6, color=TEXT_SUB)
1229
+ ax4_l.legend(loc="upper center", bbox_to_anchor=(0.5, -0.09), ncol=2, facecolor=BG_PANEL, edgecolor=BORDER_COLOR, fontsize=8.6, labelcolor=TEXT_MAIN)
1230
+
1231
+ # Order for Right Panel (beyond_confirmation N=1,025 Non-Circular LOTO)
1232
+ y_bc_cat11 = d["beyond_cat11_y_true"]
1233
+ bc_cat_spec = [
1234
+ (6, "Audiobook"),
1235
+ (8, "Ebook"),
1236
+ (4, "Comic"),
1237
+ (0, "Movie"),
1238
+ (1, "TV Show"),
1239
+ (5, "Game"),
1240
+ (7, "Software"),
1241
+ (9, "Course"),
1242
+ (2, "Adult / XXX"),
1243
+ (3, "Music"),
1244
+ ]
1245
+ cats_bc_labels = []
1246
+ bc_ultra, bc_int8, bc_gpt, bc_gem = [], [], [], []
1247
+ chart4_bc_manifest: Dict[str, Any] = {}
1248
+ for c_idx, c_title in bc_cat_spec:
1249
+ mask = (y_bc_cat11 == c_idx)
1250
+ n_c = int(np.sum(mask))
1251
+ cats_bc_labels.append(f"{c_title} (n={n_c:,})")
1252
+ u_v = float(np.mean(d["beyond_cat11_corr_ultra"][mask]) * 100.0)
1253
+ i_v = float(np.mean(d["beyond_cat11_corr_int8_hyb"][mask]) * 100.0)
1254
+ gp_v = float(np.mean(d["beyond_cat11_corr_gpt_noncirc"][mask]) * 100.0)
1255
+ gm_v = float(np.mean(d["beyond_cat11_corr_gemini_noncirc"][mask]) * 100.0)
1256
+ bc_ultra.append(round(u_v, 2))
1257
+ bc_int8.append(round(i_v, 2))
1258
+ bc_gpt.append(round(gp_v, 2))
1259
+ bc_gem.append(round(gm_v, 2))
1260
+ chart4_bc_manifest[c_title] = {
1261
+ "n": n_c,
1262
+ "armiger_ultra_pct": round(u_v, 2),
1263
+ "armiger_int8_pct": round(i_v, 2),
1264
+ "gpt_noncirc_pct": round(gp_v, 2),
1265
+ "gemini_noncirc_pct": round(gm_v, 2),
1266
+ }
1267
+
1268
+ style_ax(ax4_r)
1269
+ ax4_r.barh(y_c - 1.5 * h, bc_ultra, height=h, color=C_ULTRA, label="Armiger Ultra Fair Hybrid (95.12% Non-Circular)", zorder=3)
1270
+ ax4_r.barh(y_c - 0.5 * h, bc_int8, height=h, color=C_INT8, label="Armiger INT8 + ZeroCue (95.12% Non-Circular, 92.88% Raw)", zorder=3)
1271
+ ax4_r.barh(y_c + 0.5 * h, bc_gpt, height=h, color=C_GPT, label="OpenAI GPT gpt-6-luna (95.12% Non-Circ | 96.59% Circ)", zorder=3)
1272
+ ax4_r.barh(y_c + 1.5 * h, bc_gem, height=h, color=C_GEMINI, label="Google Gemini 3.8-flash-low (93.80% Non-Circ | 95.61% Circ)", zorder=3)
1273
+ ax4_r.set_yticks(y_c)
1274
+ ax4_r.set_yticklabels(cats_bc_labels, fontsize=10, fontweight="bold", color=TEXT_MAIN)
1275
+ ax4_r.set_ylim(len(cats_bc_labels) - 0.35, -0.6)
1276
+ ax4_r.set_xlim(0, 128)
1277
+ ax4_r.set_xticks([0, 20, 40, 60, 80, 100])
1278
+ ax4_r.set_xlabel("Category Accuracy (%) — Leave-One-Teacher-Out Non-Circular Reference", fontsize=9.8, color=TEXT_SUB, labelpad=8)
1279
+ ax4_r.set_title("2. Per-Category Accuracy vs. Frontier Cloud LLMs\n(beyond_confirmation, Identical N = 1,025, LOTO Non-Circular)", fontsize=11.5, fontweight="bold", color=TEXT_MAIN, pad=10)
1280
+ for idx in range(len(cats_bc_labels)):
1281
+ ax4_r.text(bc_ultra[idx] + 1.0, idx - 1.1 * h, f"{bc_ultra[idx]:.1f}%", va="center", ha="left", fontsize=8.0, fontweight="bold", color=C_ULTRA_EDGE)
1282
+ ax4_r.text(bc_gpt[idx] + 1.0, idx + 0.5 * h, f"{bc_gpt[idx]:.1f}%", va="center", ha="left", fontsize=7.6, color=C_GPT)
1283
+ ax4_r.text(bc_gem[idx] + 1.0, idx + 1.5 * h, f"{bc_gem[idx]:.1f}%", va="center", ha="left", fontsize=7.6, color=C_GEMINI)
1284
+ ax4_r.legend(loc="upper center", bbox_to_anchor=(0.5, -0.09), ncol=2, facecolor=BG_PANEL, edgecolor=BORDER_COLOR, fontsize=8.6, labelcolor=TEXT_MAIN)
1285
+
1286
+ sha_chart4 = save_clean_rgb_png(fig4, assets_dir / "armiger_categorical_breakdown.png")
1287
+
1288
+ # ==========================================================================
1289
+ # FIVE-SPLIT SUMMARY TABLE STATS
1290
+ # ==========================================================================
1291
+ five_split_summary: Dict[str, Any] = {}
1292
+ for sp_code, sp_label, n_exp in [
1293
+ ("oct15", "oct15_confirmation", 2835),
1294
+ ("fresh", "fresh_confirmation", 1402),
1295
+ ("beyond", "beyond_confirmation", 1025),
1296
+ ("tc2000", "tc_truespec_2000", 2000),
1297
+ ("tc3000", "tc_truespec_multilang_3000", 3000),
1298
+ ]:
1299
+ y_sp = d[f"split5_{sp_code}_y_cat"]
1300
+ sp_stats = compute_paired_panel_stats(
1301
+ f"five_split_{sp_code}",
1302
+ {
1303
+ "armiger_ultra_hyb": (d[f"split5_{sp_code}_fp32_hyb_pred"] == y_sp).astype(np.float32),
1304
+ "armiger_ultra_raw": (d[f"split5_{sp_code}_fp32_raw_pred"] == y_sp).astype(np.float32),
1305
+ "armiger_int8_hyb": (d[f"split5_{sp_code}_int8_hyb_pred"] == y_sp).astype(np.float32),
1306
+ "armiger_int8_raw": (d[f"split5_{sp_code}_int8_raw_pred"] == y_sp).astype(np.float32),
1307
+ },
1308
+ ref_model="armiger_ultra_hyb",
1309
+ expected_n=n_exp,
1310
+ metric_type="mean",
1311
+ )
1312
+ five_split_summary[sp_label] = sp_stats
1313
+
1314
+ # ==========================================================================
1315
+ # WRITE CRYPTOGRAPHIC PROVENANCE MANIFEST (CHARTS_MANIFEST.json)
1316
+ # ==========================================================================
1317
+ repo_root = assets_dir.parent
1318
+ prov_hashes: Dict[str, str] = {
1319
+ "canonical_eval_vectors.npz": hashlib.sha256(npz_path.read_bytes()).hexdigest(),
1320
+ "generate_canonical_charts.py": hashlib.sha256(pathlib.Path(__file__).read_bytes()).hexdigest(),
1321
+ "assets/armiger_vs_llms_overall_and_6dims.png": sha_chart1,
1322
+ "assets/armiger_vs_llms_cost_comparison.png": sha_chart2,
1323
+ "assets/armiger_vs_torrent_classifiers_6dims.png": sha_chart3,
1324
+ "assets/armiger_categorical_breakdown.png": sha_chart4,
1325
+ }
1326
+ for opt_rel in [
1327
+ "validated_zero_cue_catalog.json",
1328
+ "armiger_ultra.fp32.onnx",
1329
+ "armiger.int8.onnx",
1330
+ "models/armiger_ultra.fp32.onnx",
1331
+ "models/armiger.int8.onnx",
1332
+ ]:
1333
+ p_opt = repo_root / opt_rel
1334
+ if p_opt.is_file():
1335
+ prov_hashes[opt_rel] = hashlib.sha256(p_opt.read_bytes()).hexdigest()
1336
+
1337
+ manifest: Dict[str, Any] = {
1338
+ "schema_version": "1.0.0",
1339
+ "bootstrap_seed": BOOTSTRAP_SEED,
1340
+ "bootstrap_resamples": BOOTSTRAP_RESAMPLES,
1341
+ "invariants_verified": {
1342
+ "identical_denominator_lock": True,
1343
+ "anti_circularity_lock": True,
1344
+ "paired_uncertainty_and_significance": True,
1345
+ "png_metadata_stripped_ihdr_idat_iend_only": True,
1346
+ },
1347
+ "anti_circularity_audit": anti_circ_checks,
1348
+ "provenance_sha256": prov_hashes,
1349
+ "charts": {
1350
+ "armiger_vs_llms_overall_and_6dims.png": {
1351
+ "sha256": sha_chart1,
1352
+ "composite_6dim_mean": composite_stats,
1353
+ "panel_2a_category_11class": p2a_stats,
1354
+ "panel_2b_catalog_matching": p2b_stats,
1355
+ "panel_2c_audio_strict_229": p2c_stats,
1356
+ "panel_2d_anime_valid_636": p2d_stats,
1357
+ "panel_2e_junk_balanced_977": p2e_stats,
1358
+ "panel_2f_swarm_public_757": p2f_pub_stats,
1359
+ "panel_2f_swarm_warehouse_10278": p2f_whse_stats,
1360
+ },
1361
+ "armiger_vs_llms_cost_comparison.png": {
1362
+ "sha256": sha_chart2,
1363
+ "models": models_cost,
1364
+ "batched_usd_per_1m": batched_cost,
1365
+ "realtime_usd_per_1m": realtime_cost,
1366
+ },
1367
+ "armiger_vs_torrent_classifiers_6dims.png": {
1368
+ "sha256": sha_chart3,
1369
+ "panel_1_category_11class_oct15": c3_p1_stats,
1370
+ "panel_1_video_mvtv_oct15": c3_p1_vid_stats,
1371
+ "panel_2_catalog_matching_oct15": c3_p2_stats,
1372
+ "panel_3_audio_strict_oct15": c3_p3_stats,
1373
+ "panel_4_anime_oct15": c3_p4_oct_stats,
1374
+ "panel_4_anime_dub_tc2000": c3_p4_tc2k_stats,
1375
+ "panel_5_adult_oct15": c3_p5_stats,
1376
+ "panel_6a_junk_oct15": c3_p6a_stats,
1377
+ },
1378
+ "armiger_categorical_breakdown.png": {
1379
+ "sha256": sha_chart4,
1380
+ "left_oct15_confirmation_n2835": chart4_oct_manifest,
1381
+ "right_beyond_confirmation_n1025_loto": chart4_bc_manifest,
1382
+ },
1383
+ },
1384
+ "five_split_category_summary": five_split_summary,
1385
+ }
1386
+ manifest_path.parent.mkdir(parents=True, exist_ok=True)
1387
+ manifest_path.write_text(json.dumps(manifest, indent=2, sort_keys=False) + "\n", encoding="utf-8")
1388
+ return manifest
1389
+
1390
+
1391
+ def main() -> None:
1392
+ parser = argparse.ArgumentParser(description="Generate canonical Armiger benchmark charts and CHARTS_MANIFEST.json.")
1393
+ here = pathlib.Path(__file__).resolve().parent
1394
+ parser.add_argument("--vectors", type=pathlib.Path, default=here / "canonical_eval_vectors.npz")
1395
+ parser.add_argument("--assets-dir", type=pathlib.Path, default=here.parent / "assets")
1396
+ parser.add_argument("--manifest", type=pathlib.Path, default=here / "CHARTS_MANIFEST.json")
1397
+ args = parser.parse_args()
1398
+
1399
+ manifest = build_all_charts_and_manifest(args.vectors, args.assets_dir, args.manifest)
1400
+ for name, info in manifest["charts"].items():
1401
+ print(f"[OK] {name:46s} sha256={info['sha256'][:16]}...")
1402
+ print(f"[OK] Wrote {args.manifest}")
1403
+
1404
+
1405
+ if __name__ == "__main__":
1406
+ main()
benchmarks/test_chart_integrity.py ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Automated integrity and statistical invariant test suite for the canonical
3
+ Armiger & Armiger Ultra chart and benchmark pipeline.
4
+ """
5
+ from __future__ import annotations
6
+
7
+ import hashlib
8
+ import json
9
+ import pathlib
10
+ import sys
11
+
12
+ import numpy as np
13
+ import pytest
14
+
15
+ BENCH_DIR = pathlib.Path(__file__).resolve().parent
16
+ REPO_ROOT = BENCH_DIR.parent
17
+ if str(BENCH_DIR) not in sys.path:
18
+ sys.path.insert(0, str(BENCH_DIR))
19
+
20
+ from generate_canonical_charts import ( # noqa: E402
21
+ BOOTSTRAP_RESAMPLES,
22
+ BOOTSTRAP_SEED,
23
+ assert_identical_denominator,
24
+ assert_non_circular_teacher_eval,
25
+ build_all_charts_and_manifest,
26
+ compute_paired_panel_stats,
27
+ verify_png_chunks_clean,
28
+ )
29
+
30
+
31
+ def test_identical_denominator_lock_enforced():
32
+ """Verify that any denominator mismatch across models on a panel raises AssertionError."""
33
+ v_1025 = np.ones(1025, dtype=np.float32)
34
+ v_1009 = np.ones(1009, dtype=np.float32) # Dropped 16 'unknown' items
35
+ v_2835 = np.ones(2835, dtype=np.float32)
36
+ v_2825 = np.ones(2825, dtype=np.float32) # Dropped 10 'unknown' items
37
+ v_545 = np.ones(545, dtype=np.float32)
38
+ v_849 = np.ones(849, dtype=np.float32) # Mismatched audio language split
39
+
40
+ assert assert_identical_denominator("ok_1025", {"ultra": v_1025, "gpt": v_1025}, expected_n=1025) == 1025
41
+
42
+ with pytest.raises(AssertionError, match="Identical Denominator Lock violated"):
43
+ assert_identical_denominator("bad_beyond_unknown_drop", {"ultra": v_1025, "gpt": v_1009})
44
+
45
+ with pytest.raises(AssertionError, match="Identical Denominator Lock violated"):
46
+ assert_identical_denominator("bad_oct15_unknown_drop", {"ultra": v_2835, "mimmo": v_2825})
47
+
48
+ with pytest.raises(AssertionError, match="Identical Denominator Lock violated"):
49
+ assert_identical_denominator("bad_audio_split_mix", {"ultra": v_545, "gpt": v_849})
50
+
51
+ with pytest.raises(AssertionError, match="Expected N=636"):
52
+ assert_identical_denominator("bad_expected_n", {"ultra": np.ones(650), "gpt": np.ones(650)}, expected_n=636)
53
+
54
+ v_nan = v_1025.copy()
55
+ v_nan[0] = np.nan
56
+ with pytest.raises(AssertionError, match="NaN"):
57
+ assert_identical_denominator("bad_nan", {"ultra": v_1025, "gpt": v_nan})
58
+
59
+
60
+ def test_anti_circularity_lock_enforced():
61
+ """Verify that scoring a teacher model against its own circular majority vote raises AssertionError."""
62
+ d = np.load(BENCH_DIR / "canonical_eval_vectors.npz")
63
+
64
+ with pytest.raises(AssertionError, match="Anti-Circularity Lock violated"):
65
+ assert_non_circular_teacher_eval("OpenAI GPT (gpt-6-luna)", eval_mode="circular_majority", self_vote_weight=0.333)
66
+
67
+ with pytest.raises(AssertionError, match="Anti-Circularity Lock violated"):
68
+ assert_non_circular_teacher_eval("Google Gemini (gemini-3.8-flash-low)", eval_mode="leave_one_teacher_out", self_vote_weight=0.5)
69
+
70
+ gpt_audit = assert_non_circular_teacher_eval(
71
+ "OpenAI GPT (gpt-6-luna)",
72
+ eval_mode="leave_one_teacher_out",
73
+ self_vote_weight=0.0,
74
+ noncirc_vec=d["beyond_cat11_corr_gpt_noncirc"],
75
+ circ_vec=d["beyond_cat11_corr_gpt_circ"],
76
+ )
77
+ assert gpt_audit["non_circular_pct"] == 95.12
78
+ assert gpt_audit["circular_self_vote_pct"] == 96.59
79
+ assert gpt_audit["circularity_inflation_pp"] > 1.0
80
+
81
+ gem_audit = assert_non_circular_teacher_eval(
82
+ "Google Gemini (gemini-3.8-flash-low)",
83
+ eval_mode="leave_one_teacher_out",
84
+ self_vote_weight=0.0,
85
+ noncirc_vec=d["beyond_cat11_corr_gemini_noncirc"],
86
+ circ_vec=d["beyond_cat11_corr_gemini_circ"],
87
+ )
88
+ assert gem_audit["non_circular_pct"] == 93.80
89
+ assert gem_audit["circular_self_vote_pct"] == 95.61
90
+ assert gem_audit["circularity_inflation_pp"] > 1.5
91
+
92
+
93
+ def test_eval_vectors_privacy_and_dtypes():
94
+ """Verify that canonical_eval_vectors.npz contains only numeric int16/float32 arrays and zero strings."""
95
+ npz_path = BENCH_DIR / "canonical_eval_vectors.npz"
96
+ assert npz_path.is_file()
97
+ d = np.load(npz_path, allow_pickle=False)
98
+ assert len(d.files) >= 140
99
+ for k in d.files:
100
+ arr = d[k]
101
+ assert arr.dtype in (np.int16, np.float32), f"Array {k} has disallowed dtype {arr.dtype}"
102
+ assert arr.ndim == 1, f"Array {k} must be 1D, got shape {arr.shape}"
103
+ assert not np.isnan(arr).any(), f"Array {k} contains NaNs"
104
+
105
+
106
+ def test_paired_bootstrap_and_mcnemar_reproducibility():
107
+ """Verify that paired bootstrap 95% CIs and McNemar p-values are 100% deterministic."""
108
+ d = np.load(BENCH_DIR / "canonical_eval_vectors.npz")
109
+ vecs = {
110
+ "Armiger Ultra": (d["oct15_aud545_pred_ultra"] == d["oct15_aud545_y_en"]).astype(np.float32),
111
+ "Armiger INT8": (d["oct15_aud545_pred_int8_hyb"] == d["oct15_aud545_y_en"]).astype(np.float32),
112
+ "GuessIt": (d["oct15_aud545_pred_guessit"] == d["oct15_aud545_y_en"]).astype(np.float32),
113
+ "GPT-6-Luna": (d["oct15_aud545_pred_gpt"] == d["oct15_aud545_y_en"]).astype(np.float32),
114
+ }
115
+ res1 = compute_paired_panel_stats("test_aud545", vecs, ref_model="Armiger Ultra", expected_n=545)
116
+ res2 = compute_paired_panel_stats("test_aud545", vecs, ref_model="Armiger Ultra", expected_n=545)
117
+ assert res1 == res2
118
+ for m, st in res1["models"].items():
119
+ assert st["n"] == 545
120
+ assert st["ci95_lo"] <= st["point_pct"] <= st["ci95_hi"]
121
+ assert 0.0 <= st["p_value_vs_ref"] <= 1.0
122
+ assert res1["models"]["Armiger Ultra"]["point_pct"] == 97.80
123
+ assert res1["models"]["GuessIt"]["point_pct"] == 94.86
124
+ assert res1["models"]["GPT-6-Luna"]["point_pct"] == 94.68
125
+ assert res1["models"]["GPT-6-Luna"]["p_value_vs_ref"] < 0.01
126
+
127
+
128
+ def test_manifest_sha256_and_png_chunks(tmp_path: pathlib.Path):
129
+ """Verify CHARTS_MANIFEST.json provenance hashes, PNG chunk hygiene, and byte-exact determinism."""
130
+ manifest_path = BENCH_DIR / "CHARTS_MANIFEST.json"
131
+ assert manifest_path.is_file(), "CHARTS_MANIFEST.json missing"
132
+ manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
133
+
134
+ assert manifest["bootstrap_seed"] == BOOTSTRAP_SEED
135
+ assert manifest["bootstrap_resamples"] == BOOTSTRAP_RESAMPLES
136
+ for k, v in manifest["invariants_verified"].items():
137
+ assert v is True, f"Invariant {k} not verified"
138
+
139
+ # Verify all provenance SHA-256 hashes match disk
140
+ for rel_path, expected_sha in manifest["provenance_sha256"].items():
141
+ target = (BENCH_DIR / rel_path) if (BENCH_DIR / rel_path).is_file() else (REPO_ROOT / rel_path)
142
+ assert target.is_file(), f"Provenance file missing: {rel_path}"
143
+ actual_sha = hashlib.sha256(target.read_bytes()).hexdigest()
144
+ assert actual_sha == expected_sha, f"SHA-256 mismatch for {rel_path}: {actual_sha} != {expected_sha}"
145
+
146
+ # Verify all 4 PNGs have only IHDR, IDAT, IEND chunks and RGB mode
147
+ for chart_name, chart_meta in manifest["charts"].items():
148
+ png_path = REPO_ROOT / "assets" / chart_name
149
+ assert png_path.is_file(), f"Chart missing: {png_path}"
150
+ chunks = verify_png_chunks_clean(png_path)
151
+ assert chunks[0] == "IHDR" and chunks[-1] == "IEND"
152
+ assert set(chunks).issubset({"IHDR", "IDAT", "IEND"})
153
+
154
+ # Re-run pipeline into tmp_path and verify byte-exact determinism of all 4 PNGs
155
+ tmp_assets = tmp_path / "assets"
156
+ tmp_manifest = tmp_path / "CHARTS_MANIFEST.json"
157
+ re_manifest = build_all_charts_and_manifest(
158
+ BENCH_DIR / "canonical_eval_vectors.npz",
159
+ tmp_assets,
160
+ tmp_manifest,
161
+ )
162
+ for chart_name, chart_meta in manifest["charts"].items():
163
+ assert re_manifest["charts"][chart_name]["sha256"] == chart_meta["sha256"], (
164
+ f"Non-deterministic PNG output for {chart_name}"
165
+ )
166
+
167
+
168
+ def test_readme_tables_match_charts_manifest():
169
+ """Verify README.md contains canonical CHARTS_MANIFEST.json metrics and zero stale numbers."""
170
+ readme_path = REPO_ROOT / "README.md"
171
+ assert readme_path.is_file()
172
+ text = readme_path.read_text(encoding="utf-8")
173
+
174
+ # Canonical numbers that must appear in README
175
+ for required_token in ("95.49%", "97.30%", "96.53%", "97.80%", "96.83%"):
176
+ assert required_token in text, f"Missing canonical metric {required_token} in {readme_path}"
177
+
178
+ # Stale pre-audit numbers that must never reappear in README
179
+ for stale_token in ("97.13%", "96.35%", "72.35%", "35.29%", "97.55%"):
180
+ assert stale_token not in text, f"Stale metric {stale_token} found in {readme_path}"