Commit History
-
fix: bound char-level inference length to the model's token limit
Paul Clark +1: Claude Fable 5The transformers pipeline's truncation=True proved unreliable across versions, so cap raw characters before char-spacing (~1 token/char) to guarantee the sequence stays under 512 tokens. Prevents an embedding IndexError on long ciphertexts with a char-level model, in both the app and the evaluator. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>9b8dd68 -
feat: char-level inference parity + free-Colab training notebook
Paul Clark +1: Claude Fable 5Makes the --char-level model actually usable in production and gives a zero-cost path to train it. - char_tokenize_text() moved to core.py (pure string op, shared by trainer, app, and evaluator) - train_transformer.py records char_level in the model config so it serializes to config.json and travels to the Hub - app.py and evaluate_baseline.py detect a char-level model from its config and apply the SAME char spacing at inference. Without this a char-level model gets raw text in production and predicts garbage (train/serve skew). - notebooks/train_on_colab.ipynb: open in Colab, pick the free T4 GPU, paste a free HF write token, run — trains the char-level classifier and pushes it to the Hub with no paid GPU Space. DEPLOY.md documents this as the easy path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>dce1610
-
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 -
fix(heuristic): range-based numeric cipher discrimination + Voynich detection
Paul ClarkTier 1b (numeric) improvements: - culper_ring: 3-digit tokens 70%+ in 800-999 range - vic: unspaced digits len>=35 -> vic; shorter -> straddling_checkerboard - nomenclator: bimodal distribution (50%+ in 1-26 PLUS 1+ in 50-99) - aeneas_tacticus: all tokens 1-26 only - wallis_cipher: 90 or 91 appears 2+ times as structural group markers - nihilist: all values >=22 (Polybius sums), strict below-22 exclusion - homophonic: fallback for broad 00-99 distribution Tier 1a addition: - voynich_render: all-lowercase alpha-space text with word_score < 2 Spot-check accuracy on 30 examples per label: culper_ring 28/30, aeneas_tacticus 30/30, nihilist 30/30, wallis_cipher 30/30, nomenclator 27/30, voynich_render 30/3012b96e8
-
Make Space HF-launch-ready: fix boot crash, add solver, expand eval, polish UX
Paul Clark +1: Claude Opus 4.7 (1M context)The Space had a hard boot crash (unsupported aria_label= kwargs on Gradio 4.44 Textbox/Dropdown/Button) plus three pre-existing test failures and several open roadmap items. This bundles the launch-readiness work into one commit: - app.py: remove all 10 aria_label= kwargs (boot-blocker on HF Spaces); add a Solve Substitution tab driving a hill-climbing solver; add a Random Example button to Detect Mode; replace ad-hoc accessibility hints with Gradio info=. - core.py: hill_climb_substitution() with frequency-rank seed, English bigram log-prob scoring with unigram backoff, and random restarts. Tighten the heuristic so plaintext doesn't get misclassified as caesar_rot when the best Caesar shift is 0. - scripts/evaluate_baseline.py: per-difficulty and per-length-bucket accuracy + macro-F1 breakdowns alongside the overall metrics, for both heuristic and Transformer paths. - requirements.txt: pin torch>=2.2.0 so transformers.pipeline actually loads on a fresh Space. - tests/…fede36d -
10/10 polish: Compare Mode, Kasiski/Friedman, rich dataset schema, expanded tests/docs
Paul Clarkd634e85 -
Initial Cipher Detective AI public foundation
Paul Clarkf90a967