Skip to content

Feat/campaign methodology instruments - #6

Merged
0xdiid merged 14 commits into
mainfrom
feat/campaign-methodology-instruments
Jul 30, 2026
Merged

Feat/campaign methodology instruments#6
0xdiid merged 14 commits into
mainfrom
feat/campaign-methodology-instruments

Conversation

@0xdiid

@0xdiid 0xdiid commented Jul 30, 2026

Copy link
Copy Markdown
Owner

No description provided.

0xdiid and others added 14 commits July 30, 2026 09:36
…g schedule

Given a per-position class `schedule` (a k-value additive selector, e.g. derived
from a related message), fit shift(i)=a[i%period]+d[schedule[i]] FREELY (the
period-p additive plus per-class offsets) by monogram coordinate ascent, then
z-score the de-keyed IoC against the same fit on SHUFFLED schedules.

An additive shift is a bijection within each residue class, so the period-p key is
un-recoverable from the ciphertext alone (every within-class statistic is
invariant). Conditioning on the schedule defeats that: each (i%period, class) cell
is a pure Caesar, so the de-keyed IoC snaps toward the language's iff the schedule
is real. Fitting the key freely — rather than pinning it to a noisy alignment
estimate before testing the schedule — is what makes a real schedule detectable.
`max_offset` bounds the offsets to a "slight variation" range.

Test (true schedule snaps z~7 / shuffled z~0), CHANGELOG; ruff + mypy clean;
full "not slow" suite green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EJjjwhsWqwb5GRvD4QiA5i
census: family-level exclusion instrument (which families can emit an observed
statistic at the observed length, with structural infeasibility reported apart
from distributional misses).
crib_csp: known-plaintext recovery for bifid5(+p7 additive) as CP-SAT constraint
propagation — register-free, UNSAT is a proof, longer cribs strictly help.
evidence: Finding refuses to render without plant gate + matched null + coverage
+ family-size correction.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrpA9d1jGn7fzbB1aV61JK
…ct, scoped closures, VOID state

searched_fraction/Coverage.of_axes: intended-space size is the product of the
declared free axes, so a coverage claim cannot silently hold an axis fixed.
with_power: a negative whose measured power on same-shape plants is below
MIN_POWER_Z renders as 'silent' — the statistic could not have seen the signal.
scoped: a complete negative that names what it does NOT close renders as
'closed (scoped)' with reopen conditions, so it cannot be quoted as a family kill.
voided: a broken-instrument result renders as 'void', distinguishable from a
trusted null and citable as neither positive nor negative.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrpA9d1jGn7fzbB1aV61JK
…le vs 2-sample labeling, per-family power

expected_null_max/bank_scaling: the expected max of a noise bank grows like
sqrt(2 ln n) — compute the margin BEFORE scaling a candidate bank, because a
test justified at n=200 can have zero power left at n=7000.
labeling_power: 2-sample AUC and held-out 1-sample accuracy answer different
questions; quoting the former for a one-ciphertext claim is a measured false-
closure mode. Returns both.
family_power: per-family plant calibration (z vs matched null on each plant,
P(z >= threshold)) — converts any statistic into a detector with measured
power, feeding evidence.Finding.with_power.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrpA9d1jGn7fzbB1aV61JK
…is invariant under

null_is_degenerate + NullResult.degenerate encode the selection rule: an honest
null preserves what the objective is GIVEN and destroys what it puts UNDER TEST.
A statistic that is a function of what the null preserves (e.g. coset multisets
under a coset-preserving shuffle) yields a point-mass null distribution that can
never be beaten — its p=1 reads exactly like a real negative and is now flagged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrpA9d1jGn7fzbB1aV61JK
…or-normalized cross-model scores

GaugeNormalizedScorer: an omitted/relabelled alphabet letter is a GAUGE — the
correct decode emerges Caesar-shifted and the n-gram model scores it as junk,
leaving the climb with no gradient toward the answer (one wrong gauge value was
a measured 84% of a score cliff). Normalizing the shift away inside the
objective (unigram chi-squared picks it, then the n-gram model scores) makes
all 26 frames reachable from a single search.
excision_score: score exactly the letters a contamination hypothesis claims are
language — max over removing a contiguous k-block or one mod-width column —
instead of letting an embedded key block drag every placement to junk.
NgramScorer.anchored / anchored_score: normalize any model to its own
random/language anchors so scores are comparable across models; a route-register
decode sits at the English model's ghost ceiling but ~1.0 register-matched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrpA9d1jGn7fzbB1aV61JK
…e-pad annihilator

harmonic_corroboration: a real period p FORCES elevation at 2p (its cosets are
subsets), so {p,2p} is one signal, not two multiplicity draws — a cheap
refutation lever for a pinned period claim, complementing the scan-wide
period_family_significance.
lag_difference_scan: IoC of the mod-26 lag-L difference stream — goes
plaintext-like for a cycled running key (difference of two English letters) and
IS the plaintext for a ciphertext autokey at lag L (head returned for reading).
Empirical permutation null with scan-max correction; the analytic iid variance
is measured-wrong here (overlap dependence, z≈6 on random text).
separable_pad_annihilator: key-free detector for k[i]=a[i%p]+b[i%q] — lag-p
difference cancels a, per-mod-q-class best-shift LLR against the predicted
letter-difference distribution absorbs b. The tempting both-streams-at-once
second difference is POWERLESS (two convolutions flatten English to uniform,
measured z≈0); this design measures z≈3 at 450 letters, z≈7 at 1200.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrpA9d1jGn7fzbB1aV61JK
…er cliff detector

Generic (key, neighbors, objective) landscape profiling to run on a plant BEFORE
scaling a search. Probe A: is the truth even a local max — a failure is a verdict
on the objective, no search improvement helps. Probe B: do seeded steepest-ascent
climbs reach truth (basin size); verdicts identifiable / needs-richer-seeds /
dead-lane. Probe C (crib_floor): recovery rate vs letters locked to truth — the
honest 'how much crib does the attack need' number. damage_ladder: score vs key
damage with adjacent-level AUC; flags the cliff shape (first gap carries >=70%
of the drop, deeper rungs stop separating) where 'SA reached 84% of the score'
means nothing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrpA9d1jGn7fzbB1aV61JK
…er the cipher registry

Fingerprint statistics rank families; solvers exclude them (a family can match
eight statistics at mean |z| 0.4 and still be decode-refuted with power). This
runs each registered cracker at the target's exact length on its own genuine
plant (GATE), random letters (CTRL — never an absolute bar, search inflates
structureless scores), and the target, anchoring the target between the bands.
A solver whose gate never separates from its ctrl at this length is UNGATED and
its row is suppressed rather than believed. length_threshold sweeps n to
separate 'cipher is unclimbable' from 'text is too short'.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrpA9d1jGn7fzbB1aV61JK
…sweep

embed plants k non-language characters in the shapes real constructions embed
them (contiguous block, scattered interrupters, grid column, periodic coset);
sensitivity_sweep measures how far each shape/size moves a statistic off its
clean value and reports the per-shape insert BUDGET — the k at which an
exclusion built on that statistic dissolves. An exclusion quoted without its
insert budget silently assumes a pure payload.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrpA9d1jGn7fzbB1aV61JK
…ore its negatives count

Tier A reproduces a solved sibling case within top-N (catches harness rot
end-to-end: wrong plumbing, broken scoring, a solver scoring heap garbage).
Tier B recovers the attack's own planted structure at the target length, built
by THIS module's trusted encoder — never the attack under test, so a
self-consistently-wrong implementation cannot pass on its own mis-encoding.
A failed tier makes the attack VOID — distinct from a negative — and the result
feeds evidence.Finding.voided directly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrpA9d1jGn7fzbB1aV61JK
…s/telegraphic/numeric registers

Plant-gate recall is register-specific: a null proven on prose plants does not
transfer to wordlist/coded/telegraphic payloads. register_corpus synthesizes
deterministic corpora per register for (a) register-diverse plant gates and
(b) register-matched genre models, gated by the rule that a register model must
beat the prose model on its own register before any search runs behind it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrpA9d1jGn7fzbB1aV61JK
…gn identifiers

Puzzle-specific identifiers (puzzle tags, campaign-exact axis sizes) replaced
with neutral equivalents in docstrings, tests and the changelog — the library
stays campaign-agnostic per the repo's convention.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrpA9d1jGn7fzbB1aV61JK
…or mypy

The base class lives on the module object returned by the lazy ortools import
(what keeps [csp] an optional extra), which mypy cannot resolve as a name.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrpA9d1jGn7fzbB1aV61JK
@0xdiid
0xdiid merged commit c301c44 into main Jul 30, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant