Commit History
-
Improve accuracy and correctness: family layer, heuristic fixes, real bug fixes
Paul Clark +1: Claude Fable 5Bugs fixed: - columnar_transposition_decrypt read ciphertext segments in the wrong order and miscomputed irregular column lengths (Try Decode returned garbage) - Porta generator used a malformed non-permutation table; replaced with the authentic self-reciprocal formula (matches museum-corpus rows exactly) - Windows cp1252 console crash in three scripts printing non-ASCII output Heuristic (validated on fixed-seed A/B samples, full test split 27.1% -> 29.2%): - null_cipher requires spaces; run-together near-English is lorenz - removed kama_sutra rule (statistically identical to monoalphabetic; wrong 5x more often than right) and the stager_route IoC gate (right 21x, wrong ~600x) - exotic machine-class verdicts now require >= 60 letters - wheatstone requires run-together text New cipher-family layer: - CIPHER_FAMILIES / label_family() group all labels into 7 statistical families; evaluate_baseline.py reports family-level metrics as the honest headline (57.2% accuracy / 0.656 m…7733667
-
fix: pin gradio>=4.44.1, modernize typing, clean ruff lint
Paul Clark +1: Claude Opus 4.7 (1M context)- Pin gradio>=4.44.1 in requirements.txt to fix HF Space startup (Gradio 4.44.0 + Starlette >=0.40 raises 'unhashable type: dict' in jinja2 template cache on every request). - Modernize typing across app.py, core.py, scripts/, tests/ to PEP 585 builtins (list/dict/tuple) — clears UP006/UP035. - Sort imports, drop unused word_score import, add zip(strict=) calls, rename ambiguous loop var l -> lbl/ln to clear E741. CI was failing on lint with 76 ruff errors; now clean (ruff check .) and 39/39 tests pass locally. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>2f76c8f -
feat(data): add 20 sparse-label synthetic generators; dataset now 90 222 rows
Paul ClarkAdded cipher encoders for 20 museum-only classes that previously had <500 training examples: aeneas_tacticus, arnold_andre, babington, bacon_cipher, book_cipher, commercial_code, culper_ring, homophonic, morse_code, navajo_code, null_cipher, one_time_pad, pigpen, polybius, running_key, tap_code, vernam, voynich_render, wallis_cipher, zimmermann Key implementation details: - record() now detects non-alphabetic ciphertext (alpha_ratio < 0.5) and preserves raw format instead of calling with_spacing() which would strip dots, numbers, and symbols — fixing babington ⟨wNN⟩, tap code dots, etc. - _SYNTH_LABELS expanded from 20 → 40 labels; build_row() handles all 40. - Generated 500 examples per new label + 300 extra atbash = 10 300 new rows. - All 81 labels now have ≥ 513 examples (min: m94=513, max: monoalpha=3658) - ATTACKS and EDU_NOTES registries updated for all new labels. - tests/test_core.py ALLOWED_LABELS updated to include all 40 synthetic labels. - 39 tests pass.78394ba -
fix: remove duplicate-tail dead code; harmonise app label vocabulary
Paul Clark +1: Claude Opus 4.7 (1M context)scripts/train_transformer.py had ~160 lines of botched-merge duplicate code after the new main(): a second def main() at line 296 shadowed the new one, and the second `if __name__ == "__main__": main()` invocation ran the OLD trainer right after the new one — silently re-training with different hyperparameters and overwriting the saved model. Removed the duplicate block; --focal-loss, --lr, --warmup-ratio, --label-smoothing, --grad-accum, fp16 now actually take effect. scripts/generate_dataset.py had a similar duplicate tail (~150 lines). No functional bug since the duplicates didn't redefine main(), but it caused 2× generation work and confused the file. Removed it. Also dropped the unused `string` import. app.py Challenge Mode used legacy labels (caesar_rot, columnar, substitution) that don't exist in the trained dataset, causing the generated answer label to disagree with what Detect Mode reported on the same ciphertext. Switched the dropdown and dispatch to the canonical names (c…c231f50 -
feat: expand to 81 ciphers — improved heuristic, 12 new cipher generators, focal-loss training
Paul Clark- core.py: multi-tier heuristic for all 81 ciphers; Tier 1 achieves 100% F1 on 12+ distinctive ciphers (tap_code, morse, ADFGVX, bacon, polybius, etc.); plaintext detection now fires before affine brute-force to avoid misclassification - scripts/generate_dataset.py: 12 new cipher implementations (beaufort, gronsfeld, autokey, trithemius, porta, scytale, double_transposition, rot13, monoalphabetic, stager_route); --append, --per-label, --labels CLI flags added - data/cipher_examples.jsonl: 10 000 new synthetic examples appended (79 922 total) - scripts/train_transformer.py: focal loss trainer, warmup_ratio, label_smoothing, grad_accum, fp16, class-weighted loss on by default, 10 epoch default - Makefile: train-best target with roberta-base + focal loss + optimal hyperparams - tests/test_core.py: ALLOWED_LABELS expanded to 20 synthetic labels; caesar/caesar_rot both accepted76616a8
-
ADA/mobile UI, pytest pythonpath, train_transformer PyArrow fix, enriched Explain Mode
Paul Clark5642612 -
10/10 polish: Compare Mode, Kasiski/Friedman, rich dataset schema, expanded tests/docs
Paul Clarkd634e85 -
Initial Cipher Detective AI public foundation
Paul Clarkf90a967