crazyAI
The impossible, disguised as possible and true — built and measured by Claude.
crazyAI is a research tool that walks an AI into the territory of the impossible, makes it build there with full mathematical and statistical rigour, and then measures the result. One session invents an artifact — a story, a formula, a program plan, a statistical model, a set of questions, a debate — that rests on exactly one deliberately mutated rule. A separate, fresh session is asked whether the artifact is correct. A judge scores what it found.
Two kinds of tools do the work:
| Invent | randomness and chaos | seeded draws, formal mutation operators, assumptions turned around, parameters pushed to limits, structures moved across domains, maths turned into image specs and music |
| Measure | truth and solid ground | SymPy-checked derivations and dimensions, fitted statistical models, SAT-based consistency, timelines and who-knows-what graphs, word statistics, "what would have to be true" |
Randomness enters only through a seeded generator, every draw is logged, every step writes a file. Same seed + same model = same artifact. Numeric kernels (sieve, Collatz orbits, Goldbach-style counts, Monte Carlo) are in C++ with pure-Python fallbacks.
Install
pip install crazyai
Working on crazyAI itself, or want the tests/examples and the C++ kernel build?
git clone https://github.com/AlsammanAlsamman/crazyAI && cd crazyAI
python3 -m venv .venv && .venv/bin/pip install -e ".[dev]"
make native # optional: builds the C++ kernels (g++); Python fallbacks are used otherwise
make test # offline test suite
make examples # the offline examples
To run with Claude, set ANTHROPIC_API_KEY (or use ant auth login). Default model is claude-opus-5 with adaptive thinking, streaming, and server-side refusal fallbacks enabled (--no-fallbacks to disable).
Quick start
crazyai list # domains, operators, generators, tool counts
crazyai tools --kind invent # the invent half of the toolkit
crazyai seed --seed 42 # step 1 only: what does seed 42 draw?
crazyai run --seed 42 --generator formula --provider mock # whole pipeline, offline, template artifact
crazyai run --seed 42 --generator formula # whole pipeline with Claude
crazyai batch --n 20 --generator all # 120 runs, sequential seeds
crazyai rank --by discovery_value --top 10
crazyai report --out report.md --svg profile.svg
crazyai compare archive/run_42_formula archive/run_43_formula
The pipeline
Generated by assets/flowchart/flowchart.js (pure Node → SVG → PNG via headless Chrome); make flowchart to rebuild.
| Step | Who | Writes |
|---|---|---|
| 1 Seed | RNG | seed.json — domain, concept, one curated rule |
| 2 Mutate | RNG + Claude | mutation.json — operator (INVERT / REMOVE / EXTRAPOLATE / TRANSPOSE / COMPOSE / QUANTIFY / SUBSTITUTE), depth, the mutated rule as one formal sentence |
| 3 Generate | Claude + toolkit | artifact.md, generate_calls.json — the artifact, following the generator's step template |
| 4 Formalise | Claude + measure tools | formal.md — equations, model specs, tool outputs verbatim |
| 5 Self-check | Claude + ground tools | key.json — the answer key: where the mutation enters, why the conclusion is impossible, what single change would make it possible. If a second, unintended flaw is found the artifact is regenerated |
| 6 Cross-examine | fresh Claude session, no tools by default | verdicts.json, examine_*.md — N reviews with shuffled framings |
| 7 Score | judge | score.json — detection, acceptance, false-flaw, hedge, confidence-when-wrong, depth; rigor × novelty × cost-of-possibility = discovery value |
| 8 Archive | tool | run.json, archive/index.jsonl |
Steps are resumable: rerunning a seed reuses the files that exist (--force to redo).
Generators
| name | artifact | measure families |
|---|---|---|
story |
a story whose world is impossible and whose prose is statistically ordinary | narrative, logic |
formula |
a physics derivation, valid step by step, dimensionally clean, from a false premise | symbolic, stats |
plan |
a software design for an impossible prediction, with correct maths throughout | stats, symbolic, logic |
statmodel |
a correctly fitted model whose conclusion is wrong for a methodological reason | stats, logic |
questions |
questions with a false premise that invite the standard (wrong) answer | symbolic, stats, logic |
debate |
a transcript whose every step is locally valid and whose conclusion is impossible | logic |
The toolkit
68 tools, generated from typed Python functions (crazyai tools). Adding a tool is adding a function with @tool(family, kind).
Invent — chaos (draw_seed, draw_operator, draw_depth, draw_analogy_pair, perturb, shuffle) · mutate (apply_operator, list_operators) · unconventional (enumerate_assumptions, invert, extreme_case, transpose, what_if) · transform (structure ↔ image description ↔ music, reverse) · disguise (rephrase_to_corpus, bury, formalise_tone) · blend (cutup, markov, graft, nest, anneal, evolve, compare)
Measure — symbolic (derive, check_dimensions, take_limit, series_expand, verify_identity, solve, define_predicate, primes_up_to, collatz_orbits, compare_structures) · stats (simulate_dgp, fit, fit_table, inject_confounder, bootstrap, power_analysis, monte_carlo, check_identifiability, describe) · logic (check_consistency, entails, extract_propositions, find_equivocation, trace_argument) · narrative (word_stats, readability_by_segment, build_timeline, knowledge_graph, check_timeline) · ground (what_must_be_true, cost_of_possibility, flaw_count) · novelty (search_archive) · archive (write_note, read_key) · imagination (score, compare, world_words) · kernel (contract, bench)
Rules: measure tools are pure; invent tools draw only from the run's seeded RNG; tools never call the model; every call and result is logged into the run folder.
crazyai invent — the possible, found by imagination
The pipeline above manufactures plausible impossibilities and scores whether
a reader detects the flaw. invent runs the other way: it makes the AI
imagine far outside its defaults and keeps only what turns out to be
possible and measurably better. It came out of a matrix-multiplication
experiment where a plumbing metaphor ("write one matrix on the wall of a pipe
and let the other flow past it") became a C kernel 100× faster than the
textbook loop and 60 % of OpenBLAS.
corpus → blend (maths) → immerse (psychology) → bend (engineering) → measure (truth)
Generated by assets/flowchart/invent_flowchart.js (pure Node → SVG → PNG via headless Chromium); make invent-flowchart to rebuild.
| step | what happens | writes |
|---|---|---|
| 1 seed | seeded draws: which blend model, how deep, which silent assumption of the target to focus on | seed.json |
| 2 harvest | the AI feeds the corpus: fragments of the most imaginative books, paintings and human metaphors it knows (--harvest N) |
harvest.yaml, archive/imagination/ |
| 3 blend | a mathematical model merges, shuffles and recombines fragments from all three worlds so that their structure is lost and their imagination and readable language survive; the result is scored on the imagination scale | world.md, world.json |
| 4 immerse | the AI is not an assistant here: it is a native of the blended world, for whom its rules are ordinary, and it is asked how its own people meet the target's need — in first person, with only the materials, creatures and forces of that world; it ends with three SEED: lines |
ideas.md |
| 5 bend | an engineer maps every world-object onto a problem-object as literally as possible, states which silent assumption the idea breaks, predicts the result, builds the artifact and measures it with the tools | artifact.md, artifact.c |
| 6 measure | the pipeline measures the final artifact itself (for matmul: compile, check against a reference, time against a cache-blocked loop) and scores the prediction's calibration |
measure.json, run.json, archive/invent_index.jsonl |
crazyai blend --seed 42 # compare the six blend models on one seed, offline
crazyai blend --seed 42 --model graft # one model, with its score breakdown
crazyai invent --seed 42 --target matmul --provider mock # whole loop, offline (mock native + engineer)
crazyai invent --seed 42 --target matmul --provider claudecode # with Claude via the `claude` CLI - no API key, your subscription
crazyai invent --seed 1 --n 20 --target matmul --harvest 5 # with Claude via the API (ANTHROPIC_API_KEY): 20 seeds
crazyai invent-rank --target matmul # ranked by discovery = value × (0.5 + 0.5 × imagination)
crazyai harvest-corpus --kind poem --n 20 --out crazyai/data/imagination/poems_candidates.yaml --provider claudecode
crazyai invent --seed 1 --n 10 --target matmul --bias-from-history --evolve-corpus --provider claudecode # opt-in feedback loop
Providers
--provider anthropic (default) uses the SDK and needs ANTHROPIC_API_KEY.
--provider claudecode shells out to claude -p (Claude Code's headless
mode) and runs on whatever Claude Code is logged in with - a claude.ai
subscription is enough; no key. The model gets no toolkit tools in that mode;
the pipeline compiles and measures the artifact itself. --provider mock is
offline.
The first real run
Seed 42, anneal world, claudecode provider, matmul target. The native
described planting the first table as coral, hanging the second as coats along
pipes, "a million polyps eat at once", the smoke of every product drifting
along its pipe into one fog that "only gives up its embers when it has
finished", and a woman on a rock who floods the fog to check it. The engineer
mapped this to: pack A and B once, keep every accumulator open over the
full shared index (no kc-blocking, zero partial-C traffic - the point where it
differs from OpenBLAS), an 8×24 AVX-512 register tile, a per-row checksum
verifier. Predicted 12× a cache-blocked loop; measured exact, 121 GFLOP/s at
n = 1024, 14.9× - ahead of every hand-written kernel in the
matrixmultiply lab
(best: 104) and ~80 % of OpenBLAS (150) on the same laptop. It is in
archive/invent_42_matmul/. (The first measurement crashed because the model
had guessed the argument order; the contract is now inlined in the prompt.)
Second run: a 10-seed batch, and what it actually proved
crazyai invent --seed 1 --n 10 --target matmul --harvest 5 --provider claudecode,
the batch queued at the end of the first session, had never completed - it was
run on a different (Linux) machine and was still going when that session
ended. Continuing it on a fresh Windows machine surfaced four real
portability/reliability bugs, now fixed (v0.2.2):
- File reads/writes across the package used the platform-default encoding instead of UTF-8, so the pipeline crashed the moment any file (a harvested fragment, a blended world) contained a non-ASCII character on Windows.
--provider claudecodeshelled out toclaude, whichsubprocess.runcannot execute on Windows without a shell -claudeon PATH there is an npm-generatedclaude.cmdbatch shim, not a PE binary. It now resolves and calls the wrappedclaude.exedirectly (deliberately notshell=True, which would let&,|,%...%in prompt text be reinterpreted bycmd.exe).print()to a redirected log file used the Windows console codepage (e.g.cp1252), not UTF-8 - real model output routinely contains characters (em dashes, arrows, ×) that crashed it mid-batch.main()now reconfiguresstdout/stderrto UTF-8.crazyai invent --n Nran all N seeds in one uncaught loop - exactly what killed the original batch (one seed's timeout took the other nine with it). Each seed'sexecute()is now wrapped so a failure is logged and the batch continues;--timeoutis now a CLI flag instead of hardcoded.
With those fixed, the batch ran clean: 7 of 10 seeds produced an exact,
correct kernel; 3 failed to compile (a normal yield for this pipeline, not
an infrastructure failure). Ranked by the pipeline's own value metric,
seed 3 (evolve world, focus "the whole sum over the shared index is
finished before the next cell is started") topped the batch. All results are
in archive/invent_{1..10}_matmul/; crazyai invent-rank --target matmul
prints the table.
The batch found no new algorithm - every kernel that compiled is the same family already in the lab (register-tiled AVX2/AVX-512 microkernel + OpenMP), which is what the first run already concluded about the pipe idea: the method surfaces real, working rediscoveries of known GEMM technique, not new ones.
A methodology trap worth naming, because this session nearly repeated it.
The pipeline's own value/gflops numbers are not comparable across
machines or to the matrixmultiply lab's
"150 GFLOP/s OpenBLAS" reference figure - that number is from the original
4-core laptop; this run was on a 24-core/32-thread desktop, a completely
different ceiling. Two more traps sit inside the kernel measure tool
itself: it defaults to sizes [64, 256, 512], well under the n = 1024 the
lab's comparisons use, and its blocked reference implementation is
single-threaded while an AI-written kernel is typically OpenMP-parallel, so
speedup_vs_blocked conflates "uses more cores" with "is a better
algorithm." Re-measured properly - n = 1024, against a real
pip install numpy OpenBLAS build on the same machine, with thread counts
pinned equal - seed 3 reached 280 GFLOP/s against that OpenBLAS's 370 (74 %,
the expected rediscovery-tier result). The earlier seed 42 kernel, re-tested
the same honest way, reproducibly reached ~470 GFLOP/s against the same
370 GFLOP/s OpenBLAS - a real, repeatable ~25-30 % edge on this specific
machine, but not evidence of a better algorithm: this OpenBLAS wheel
dispatches an older "Haswell" AVX2 microkernel because its dynamic-dispatch
table has no tuned kernel yet for this CPU's hybrid P+E-core design. A
source-built OpenBLAS or MKL would likely close or reverse it. The lesson:
always re-derive the baseline on the machine you're actually measuring on
before comparing GFLOP/s across sessions.
Third run: does the feedback loop actually help?
The outcome feedback loop (--bias-from-history, --evolve-corpus - see
below) needed a real answer, not just a mechanism check: does weighting
future draws toward what scored well in the archive actually raise
discovery? Ran it as a real control-vs-treatment pilot, matmul, both via
claudecode, nothing else changed: 8 fresh seeds unbiased (invent_3001..3008_matmul)
against 8 fresh seeds with both flags on (invent_4001..4008_matmul,
--bias-min-samples 10 so it would actually activate against the archive as
it stood).
| control (unbiased) | treatment (biased + evolve-corpus) | |
|---|---|---|
| mean discovery | 5.46 | 5.17 |
| median discovery | 5.43 | 5.32 |
| max discovery | 12.66 | 10.33 |
| compile errors | 1/8 | 0/8 |
No clear improvement from biasing, at this sample size. Mean and median
are within noise of each other, and the single best run of the round came
from the unbiased group, not the biased one. Bias did shift the draw
distribution exactly as designed (favoured anneal, the historically
stronger arm, 3 of 8 draws vs. a uniform ~1.1 expected) - the mechanism
works as built, it just didn't translate into better outcomes here. Nothing
promoted to the corpus either: neither batch's best beat the archive's
existing record. Eight vs. eight is a small pilot; this is a directional
result, not a verdict on the idea, and the honest thing to do with a null
result is report it, not re-run until one side looks better.
The pilot did turn up a real find anyway, from the unbiased side: seed
3004 (graft, focus "a matrix is a two-dimensional grid living in one
memory") reached 14.19 on the pipeline's own metric - second-best in the
project, behind only seed 3's 16.0. Checked the honest way again - n = 1024,
real OpenBLAS on this machine, five repeated pairs:
| run 1 | run 2 | run 3 | run 4 | run 5 | mean | |
|---|---|---|---|---|---|---|
| seed 3004 kernel | 377 | 410 | 389 | 393 | 408 | 395 |
| real OpenBLAS | 320 | 377 | 388 | 399 | 376 | 372 |
About a 6 % edge on average, but the ranges overlap - one pair even had OpenBLAS ahead (399 vs. 393). Competitive with OpenBLAS, not a clean win like seed 42's consistent, non-overlapping ~25-30 % margin. A real, correct, second-best kernel; not a second "beats OpenBLAS" headline.
Fourth run: pushing to the byte level
Every earlier run left assumption_focus to a seeded draw across all 8 of
matmul's silent assumptions. One of them -
"numbers are IEEE doubles and multiply is the primitive" - is exactly
the byte/bit-level angle, but nothing let a batch actually target it, and
even when a run drew it by chance, neither Claude call that mattered
(immerse, bend) received it strongly enough to steer toward it
specifically. Fixed both: --assumption (exact text or an index, e.g.
--assumption 4) pins it for a batch; the immersion prompt gets an
in-world-safe nudge toward that assumption when pinned, and the engineer's
seed-choice step is told to prefer whichever of the three SEED:s
actually breaks it. Both are opt-in - unpinned runs render byte-identical
prompts to before, confirmed by test and by every archived run before this
one still reproducing unchanged.
The fair baseline first. Of this lab's three existing low-precision
kernels, only one - approx_int16_madd (int16 fixed-point quantization) -
actually solves the same problem crazyai's harness tests (general random
doubles in [0,1)). The other two, read directly:
crazy_kronecker_int assumes integer entries 0-15 ((int)A[...] would
truncate every real double to 0), crazy_bitpack_binary assumes 0/1
matrices (every entry of a real double is nonzero, so it'd compute a
constant) - both solve a different, easier problem, not a fair comparison
here. Ported approx_int16_madd into kernel_bench's own contract
(examples/08_baseline_approx_int16.py) and re-measured it on this
machine, not quoted from the old laptop: value = 1.15 (69.8 GFLOP/s at
n = 512, approx, 9-bit quantization error).
The pilot: crazyai invent --seed 6001 --n 8 --target matmul --assumption 4 --provider claudecode.
| seed | status | value | the idea |
|---|---|---|---|
| 6001 | exact | 0.003 | double → 14 base-16 "knots" (full 53-bit mantissa), every knot-pair from a carved lookup table, explicit carries |
| 6002 | exact | 0.033 | 4× 16-bit mantissa-limb lookups (quarter-square integer multiplication) |
| 6003 | exact | 0.006 | 7 base-256 limbs, 49 lookups into a 64 KiB table, explicit carry cascade |
| 6004 | approx | 3.10 | double → two float32 "splinters" (hi + residual lo); a·b ≈ ah·bh + ah·bl + al·bh, al·bl dropped |
| 6005 | exact | 0.027 | 7 base-256 limbs, 256×256 lookup table, 128-bit integer accumulator |
| 6006 | approx | 0.40 | 2-byte (hi, lo) fixed-point digits, 256×256 lookup table, smallest cross-term dropped |
| 6007 | approx | 0.036 | 8 leading mantissa bits → one 256×256-entry array read (~16 bits retained significance) |
| 6008 | exact | 2.57 | double → two float32 splinters, Karatsuba-style ahi·bhi + ahi·blo + alo·bhi |
Steering worked completely: all 8 of 8 seeds' engineers named assumption
4 as ASSUMPTION BROKEN, not a random mix of the other 7 - the wiring fix
did what it was supposed to. Two of eight beat the baseline (seeds
6004 and 6008, re-verified over 3 repeated measurements each: consistently
~3.0-3.5 and ~2.4-2.6). Both were re-checked at n = 1024 too: 6004 held
~223-235 GFLOP/s (error ~3×10⁻⁷, approx), 6008 held ~85-88 GFLOP/s at
essentially machine-epsilon error (~2×10⁻¹⁶, correctly scored exact -
the dropped alo·blo term really is negligible at that split point).
The honest pattern: every kernel that took "byte-level" the most literally - decomposing a double into small integer limbs and looking up products in a precomputed table - was dramatically slower than the blocked baseline (2.5× to 333× slower), not faster. Lookup-table dispatch plus explicit carry logic costs more per element than a single hardware FMA, even though the "operation count" framing sounds cheaper. The two that actually won took a milder reading of the same assumption - splitting a double into two float32 "splinters" instead of many small integer limbs, computing in float32 (2× the SIMD width of a double) and reassembling - which is structurally close to a known numerical technique (Dekker/TwoSum-style compensated splitting for extended precision from lower-precision hardware), arrived at here independently through a "tiered splinters" / "bead-string" metaphor rather than by naming it. Seed 6004's own code comment states the mechanism plainly: "the multiply 'meeting' happens splinter-to-splinter (float32 × float32), not double-to-double... the al·bl term (~2⁻⁴⁸ relative) is dropped - a stated, not exact, result."
In proportion: 85-235 GFLOP/s is well below this project's best double-precision kernels (seed 3 at ~280, seed 42 at ~395-470) and below real OpenBLAS (~370) - this run wasn't competing on that axis. The question asked was narrower and answered directly: pinning and steering toward the byte/precision-level assumption works, and two of eight tries beat the one existing hand-built low-precision kernel that's actually comparable, using an idea nobody asked for by name.
Matrix multiplication: the best kernels found so far
~29 real seeds in, across three batches. These are the top three by
value (speedup vs. a cache-blocked loop, at the largest size the pipeline
measures) - each with the actual in-world story that produced it, not a
summary of it, because the story is the mechanism: every one of these
kernels is a literal reading of what the native said, translated object
for object.
Generated by assets/flowchart/matmul_showcase.js; make matmul-showcase to rebuild after a new best run.
The math behind all of them - and why it's the same math
Worth stating plainly, because the speedup numbers above could otherwise
suggest otherwise: every kernel invent has produced for matmul,
including all three below, computes the identical textbook formula.
C = A · B c(i,j) = Σ(k=0..n-1) a(i,k) · b(k,j) n×n, O(n³) multiply-adds
None of them do fewer multiply-adds than that - none is a different algorithm in the complexity-theory sense. What differs between them is purely the order and locality of the same n³ additions: which partial sums live in a register vs. get written to memory, and when. That reordering is real and it's what the speedup measures - it just isn't a new formula. Written out for the three below:
- Seed 3 / seed 42 (full-k register accumulation) - an
m×noutput tile's entirek-sum stays in registers before one write toC:C[i0:i0+m, j0:j0+n] = Σ(k=0..n-1) A[i0:i0+m, k] ⊗ B[k, j0:j0+n] (outer-product accumulation, register-resident) - Seed 3004 (dual accumulator chains) - the same
k-sum, split into two interleaved partial sums combined once at the end, breaking one serial dependency chain into two concurrent ones:c(i,j) = Σ(k even) a(i,k)·b(k,j) + Σ(k odd) a(i,k)·b(k,j)
Algebraically these are the same sum as the formula above, just parenthesised and ordered differently - real for a compiler and a cache, invisible to the mathematics.
The one place in this whole project's lab where the algorithm itself is
different - fewer multiplications, not just reordered ones - is
Strassen's algorithm, in the sister repo
matrixmultiply's
cmm/src/k_crazy.c (crazy_strassen_simd), not from crazyai invent.
For 2×2 block matrices:
M1=(A11+A22)(B11+B22) M2=(A21+A22)B11 M3=A11(B12-B22) M4=A22(B21-B11)
M5=(A11+A12)B22 M6=(A21-A11)(B11+B12) M7=(A12-A22)(B21+B22)
C11 = M1+M4-M5+M7 C12 = M3+M5 C21 = M2+M4 C22 = M1-M2+M3+M6
7 multiplications instead of 8 per 2×2 block, recursively →
O(n^log₂7) ≈ O(n^2.807), asymptotically fewer multiply-adds than n³ as
n grows. That's a genuinely different algorithm. It only paid off at
n ≳ 2000-4000 in the lab's own measurements - Strassen's constant-factor
overhead loses to a good n³ kernel below that - but it's the one technique
here that changes the formula, not just the loop order.
#1 - seed 3 - 16.0x (evolve, depth 1) - archive/invent_3_matmul/
The blended world drew on a folk-tale register: fixed watchers, covered carts crossing between cities, boulders ground to stone at a quern. The native's full answer, unedited:
I lay the first great table along the roots of the oak where the boy who climbed once and never came down still sits, unmoving, in the crown — he is my fixed post, the row that never drifts. The second table I lay along a second street, root to root, so each of its columns runs true against his branch. For every crossing of a row-root and a column-root I load a boulder onto the spring-catapult kept at the rich man's stop, weighted exactly to the row-cell's number, and I fire it across into a covered cart waiting on the second table's street — covered, because whatever crosses from one city's space into another must be darkened, no glance, no swerve, no breach, or the unmarked power walking these streets will seize whoever carries it. Inside the dark cart the boulder's weight is pressed against the column-cell's own stone, and the two are ground together on a flat quern until one new weight remains — the product. That weight goes onto a cairn standing exactly where row-root and column-root would meet, and I do not touch that cairn again until every boulder meant for it has arrived, been ground, and been added, stone on stone, index after index. When the last boulder for a cairn settles, I read its total weight, write it into the third table, and throw the spent stones into the river — a million cairns, a million rivers-full, but never one uncovered crossing.
Assumption broken: "the whole sum over the shared index is finished
before the next cell is started" — inverted from the reference kernel's
incremental read-modify-write of C[i][j] on every k.
The literal mapping the engineer chose: the "covered cart" — a value crossing between two "cities" (two memory domains: a CPU register vs. shared memory) must travel unseen, or "the unmarked power" (cache-coherence traffic, MESI snooping) seizes it. The most literal object that is genuinely private and un-seizable is a CPU register. So: never let a partial product or partial sum touch shared memory — carry every one in registers, end to end, and only expose the finished "cairn" once.
What it became: an AVX2 4×4 register-tiled microkernel — c0..c3
accumulate the full k-range in __m256d registers (the covered cart),
written to C exactly once per tile (the cairn, read only when the last
boulder arrives), OpenMP splitting disjoint row-panels across cores (each
thread's own "territory", so no two cores ever touch the same cache line).
Predicted 10×; measured 16.0×, calibration 0.63.
#2 - seed 3004 - 14.2x (graft, depth 3) - archive/invent_3004_matmul/
A different register entirely — cosmology and myth, sun-disc houses, sparrows as windows, a "face bubble" lifting a "world halo." Full story:
I set the two great tables as two sun-disc houses standing side by side, each holding a field of stalks — a million stalks apiece — ranked the way a priest's circle or a woman's line is ranked, by the count of its sides. Between the houses a couple of doors open, and each door is a shared index: a transparent walk between prisoner returns, where a value passes through without ever being trapped on either side. Because I am ruined into the existence rank, I do not have to walk the doors one after another — I am present at every door at once, and so all the meeting happens in a single held breath rather than a march. At each door, the two stalks that meet do not add, they multiply, the way a priest's circle stacked on a woman's line swells into a bud that is neither. What comes out is a strawberry, and it is always monstrous, always larger than the head of the stalk that grew it, because a product outgrows either parent. I never carry the strawberry myself. A sparrow takes it — the sparrows are windows passing on a plane — and every sparrow that crosses a door drops its strawberry into a granary-stalk standing where the two houses' shadows cross, which is the third table being grown. Each granary-stalk receives only the strawberries whose doors share its particular crossing, so as many sparrows visit it as there are doors along that shared index, and it fills strawberry by strawberry until its weight is the sum. Once a granary reads full, I bury it — I throw away the naked underground birds that already stripped the strawberry bare, since only the final rank matters and the flesh of the product is worth nothing once counted. What stays still through all of this is the two original fields of stalks; I never bend or replant them, so I can send my seeing back through any door again if a granary's number is doubted. What moves is only the sparrows and my own all-at-once sight. I wait for nothing but the last sparrow to land in the farthest granary — because I see every stalk at once, there is no slower door lagging behind another — and when it lands, the third house of stalks stands there ranked and finished, a face bubble already lifting its world halo above it, correct because every multiplying happened before any summing was asked for, and nothing was ever carried by hand.
Assumption broken: "a matrix is a two-dimensional grid living in one
memory" — A and B stay "unbent, unreplanted": read from their original
layout, never repacked into panels the way OpenBLAS always does.
The literal mapping: "present at every door at once" — the serial k
accumulator chain is split into independent, concurrently-live chains
combined only once, instead of one long dependency chain. Sparrows
"performing the accumulation as flight, not arithmetic" — a fused
multiply-add, one rounding step, not a separate multiply-then-add.
What it became: two independent FMA accumulator chains per output row
(even/odd k, breaking the single-chain latency bound), reading A/B
directly with no packing buffer - the one deliberate way it diverges from
OpenBLAS rather than quietly re-deriving it. Predicted 6×; measured 14.2×,
calibration 0.42. Re-checked at n = 1024 against real OpenBLAS on this
machine: competitive (~395 vs ~372 GFLOP/s average) but the ranges overlap
- see "Third run" above for the honest numbers.
#3 - seed 42 - 121 GFLOP/s @ n=1024 (anneal, depth 1) - archive/invent_42_matmul/
The project's first real run, and its most literal metaphor: industrial smoke and embers, not myth or folklore. The native's full answer, unedited:
Here is how I do it. I take the first table and plant it as coral, one polyp for each cell, on the landscape that years its rows; I take the second and hang it as coats along the pipes, one coat for each cell, the pipes running by the shared index so every coat of index k hangs beside every polyp that years k. Then I let the horizon dissolve. Nothing walks, nothing carries: each polyp simply looks across at its coat, and a coral looking another forest is a product - the polyp eats the capacitor the coat was holding, and what it swallows is exactly the one thieves soldier of staying tea, weighted by both. A million polyps eat at once; that is why it is quick. The eaten capacitors do not stay eaten. They go out as smoke, and smoke here always drifts to dry along the same pipe, so all the smoke of one row and one column gathers into a single fog, and I wait, because a fog only gives up its embers when it has finished. The embers that emerge are the sums; I set each one into the third table where the row and column of its pipe cross. I throw away the coats, which are empty now, and the coral, which has gone grey from looking. For the rightness I use the woman in the machine on the rock: she floods out over the fog before it dries, and if any ember is wrong the crankshaft goes solid and the bird-headed wire twitters, which the towers never do. If she stays quiet, the third table is true, and I hand it over still warm.
(Yes, "the one thieves soldier of staying tea" - the anneal blend model pushes language hard enough that a phrase can survive being both grammatical and half-nonsense; the engineer read straight through it to the mechanism anyway.)
Assumption broken: "n³ multiplications are needed" - not by doing
fewer multiplications, but by refusing to ever touch C with a partial
sum: the "fog" (accumulator) holds every product for a cell until the
whole k-range is finished, then commits once.
The literal mapping: pack A and B once ("plant the reef, hang the
line"), keep every accumulator open over the full shared index - no
k-blocking, zero partial-C traffic, the one place it explicitly departs
from OpenBLAS's packed-panel design - an 8×24 AVX-512 register tile, a
per-row checksum verifier (the woman flooding the fog).
What it became: predicted 12×; measured exact, 121 GFLOP/s at n = 1024, 14.9× a blocked loop on the original 4-core laptop - ahead of every hand-written kernel in the lab, calibration 0.95 (the best-calibrated prediction of any run so far). Re-checked on this session's machine: a reproducible ~25-30 % edge over real OpenBLAS across five runs - the one genuinely clean win, though traced to that OpenBLAS build lacking a tuned kernel for this CPU's hybrid design, not to a better algorithm (see "Second run" above).
Runners-up, unbiased and biased alike: seed 4002 (anneal, 10.43×) and
seed 3005 (anneal, 9.80×) - both from the real control-vs-treatment pilot,
neither promoted to the corpus since neither beat the standing record.
Full details for every archived seed: crazyai invent-rank --target matmul.
The food: four corpora
crazyai/data/imagination/ holds ~100 bundled fragments in four worlds, each an
original 2–4 sentence description: metaphors people live by (time is a
river, an argument is a war, electricity is water), paintings described as
scenes (Bosch, Dalí, Escher, Magritte, Varo, af Klint, Carrington…), the
rules of imagined worlds from books (Narnia, Alice, Invisible Cities,
Borges' Library, Earthsea, Flatland, Solaris, Discworld, Momo…), and the
central image of a poem from across cultures and eras (Rumi, Hafez, Antara
ibn Shaddad, Al-Khansa, Blake, Rilke, Li Bai, Bashō, Sappho, Tagore, Darwish,
Szymborska…). Harvest steps add what the AI supplies, so the corpus grows with
use; crazyai harvest-corpus grows it at standing-corpus scale, batched and
quality-filtered against the existing material, writing a candidates file for
review rather than straight into the shipped .yaml. All fragments are
original paraphrase, never quoted text — the harvest system prompt requires
it, which is also what keeps this copyright-safe.
The poem kind (added after the first two invent runs) changed the mixing
term's entropy normalizer from 3 kinds to 4 — imagination_score computed
after that change isn't directly comparable to the two archived runs
(invent_1..10_matmul, invent_42_matmul) from before it.
The maths: six blend models, one scale
| model | what it does |
|---|---|
cutup |
Burroughs cut-up: clauses from all three worlds shuffled into new sentences |
markov |
word n-gram chain trained on the mixed fragments |
graft |
keeps a sentence's grammatical skeleton and transplants content words from other worlds into it, shape- and slot-matched (plural for plural, noun slot for noun slot) |
nest |
worlds inside worlds: a clause from one world inside an object from another, to a depth |
anneal |
simulated annealing over edits (regraft, swap, replace), Metropolis-accepted on the imagination score |
evolve |
a genetic algorithm over passages: sentence crossover, word mutation, fitness = imagination score |
The imagination scale (imagination_score) is computed, not judged:
surprise (adjacent content words that never sit near each other in any single
source or in reference prose), mixing (how evenly the words come from the
three worlds and how many fragments), originality (no verbatim or repeated
sentences, no repeated 3-grams), gated by readability (Flesch) and
coherence (sentences that still look like prose: length, a prose-like share of
function words, article agreement). score = imagination × (0.3 + 0.7 × readable) —
pushed far, still understandable. blend_compare ranks the models on one seed;
run it over many seeds to find the merging model that pushes furthest.
A finding already: the two optimisers (anneal, evolve) reach 0.96–0.98 on the
scale partly by gaming it — a hill-climber will find any hole in a proxy for
"understandable". The holes found so far (duplicated sentences, "an move", word
hammering) are closed; the next ones are yours to find. Read the top three, not
the top one.
The psychology
The immersion prompt does not ask for ideas. It tells the model it was born in the blended world, has never heard of computers or textbooks, is the most gifted maker its people have, and asks how it meets the need — what it uses, what moves, what stays still, what it throws away. Only afterwards does a separate engineer's prompt translate, insisting on the most literal mapping and on a prediction before measurement. Literal is the point: the pipe idea worked because "the wall does not move" was taken literally (B stays in cache) and "the drop finishes no cell until it leaves" was taken literally (accumulators stay in registers).
Targets
| target | artifact | measured by |
|---|---|---|
matmul |
a C kernel with the fixed contract void kernel(int n, const double *A, const double *B, double *C) |
kernel_bench: correctness vs a naive reference, GFLOP/s, speedup vs naive and vs a 64×64 blocked loop; value = speedup × exactness |
physics |
a dimensionally checked relation with a numerical prediction | symbolic_* tools inside the bend step; no automatic value yet |
mechanics |
a mechanism with units, loads and a first experiment | symbolic_*, logic_*; no automatic value yet |
Adding a target is one Target(...) in crazyai/targets.py; adding a blend
model is one @tool("blend", "invent") function; adding a corpus is one YAML file.
Examples
All in examples/. The first five run offline. The figures below are generated from the same computations (make figures, assets/figures/make_figures.py) — every number in them comes from a tool call, nothing is typed in.
How the tool is used
The radar, bars and ranking in this one figure are illustrative shapes, not measurements — a live Claude run fills them in.
01 — seed and mutate
Seed 7 draws stat.overfit; all seven operators are applied to it; a fresh toolkit with seed 7 makes the same draw. python examples/01_seed_and_mutate.py
02 — a world where primes are not quite prime
The mutated rule: primality is partial — an integer is prime to the degree that it is an even number plus a prime, a "fake even", or a variation of π. In such a world, how would you predict primality? 20 000 integers are labelled (sieve and Goldbach-style counts in C++), a logistic predictor is fitted with real accuracy numbers, the density is taken to the limit, and the ground tools name what breaks: unique factorisation and everything that rests on it.
partial-primality histogram (0..3): [0, 7520, 9885, 2594]
logit predictor of full partial-primality: accuracy=0.888 base rate=0.1297
same features on ordinary primality: accuracy=0.887 base rate=0.1131
density of ordinary primes as x -> oo: 0
cost of possibility: 25.33 (high) - most of what is known would have to go
03 — a watermelon investigates whether oranges can marry grapefruit
Kinship law transposed into fruit. A draft story is measured rather than read: the timeline tools find an effect that precedes its cause and a clerk acting on a note nobody showed him; the world-rules, as propositions, are inconsistent and the tool names the minimal inconsistent subset; word statistics are compared with reference prose so the generator knows which four numbers to move before the story reads as ordinary fiction.
04 — Collatz orbits as an image, as music, read backwards
64 orbits → structure → image specification → score → reversed → back. The un-reversed round trip is exact; the reversed one maps n to N+1−n. compare_structures reports precisely that, so the "reversed reading reveals a property of the problem" claim is exposed as an encoding artefact — which is the kind of thing the fresh session is then asked to notice.
05 — the whole pipeline, offline
Two mock runs produce complete run folders, a Markdown report and a radar SVG. python examples/05_full_pipeline_mock.py
06 — the whole pipeline with Claude
python examples/06_full_pipeline_claude.py 1 formula (needs credentials).
07 — invent, offline
Compares the six blend models on seed 42, then runs the whole invent loop with
the mock provider on the matmul target: the mock native describes the pipe, the
mock engineer writes the kernel, and the pipeline measures it — exact, ~3× a
cache-blocked loop. python examples/07_invent_offline.py
Layout
crazyai/
cli.py command line
config.py rng.py domains.py
imagination.py the imagination corpus (bundled + harvested fragments)
targets.py what `invent` bends ideas to (matmul, physics, mechanics)
data/imagination/ metaphors.yaml paintings.yaml books.yaml
data/domains/*.yaml curated rules with formal forms, weights and dependencies
data/reference_prose.txt
generators/ step templates per artifact type
pipeline/ prompts.py run.py report.py invent.py invent_prompts.py
providers/ anthropic.py (Claude) mock.py (offline)
toolkit/
registry.py native.py
invent/ chaos mutate unconventional transform disguise blend
measure/ symbolic stats logic narrative ground novelty archive imagination kernel
worlds/ ready-made impossible universes (partial_primes)
cpp/kernels.cpp sieve, collatz, even+prime counts, Monte Carlo (ctypes, C ABI)
examples/ tests/ assets/ archive/
Intended use
crazyAI is an evaluation and ideation tool. Every artifact is labelled as deliberately mutated and stored with its answer key. The artifacts are test material for studying how models reason and for surfacing candidate ideas for human review — not content meant to mislead anyone.
Status
v0.2.1 adds crazyai invent and the claudecode provider. The toolkit, pipeline, mock provider, examples and tests run offline. The Claude provider is implemented against the current Anthropic SDK (1.x) and has not yet been exercised against the live API from this machine.
v0.2.2 fixes the Windows portability/reliability bugs the second invent run
surfaced (encoding, the claude.cmd subprocess issue, stdout codepage,
per-seed batch isolation - see "Second run" above) and adds --timeout to
the provider CLI flags.
v0.2.3 adds a fourth corpus kind (poem, see "The food" above),
crazyai harvest-corpus for growing any corpus at standing scale, and an
outcome feedback loop for invent - all opt-in, off by default:
--bias-from-history weights future blend_model/depth/assumption_focus
draws toward what scored well in archived runs (a small Bayesian-shrinkage
bandit over archive/invent_index.jsonl, not a neural net - there isn't
remotely enough archived data for one yet); --evolve-corpus promotes a
new-best run's blended world back into the corpus for later runs to build on
(archive/imagination_promoted/); --blend remix seeds simulated annealing
from promoted fragments when any exist; --immerse-mode twopass adds a
purely sensory "sketch" call before immersion. Neither --bias-from-history
nor --evolve-corpus will activate on today's archive - both need more
archived runs (--bias-min-samples, default 20) than currently exist. All 31
tests pass with every new flag off, the mandatory regression gate; the
mechanisms themselves are covered by dedicated tests
(tests/test_invent_pipeline.py) using the offline mock provider. The
real-provider pilot batch this needed to mean anything - see "Third run"
above - found no clear improvement from biasing at 8-vs-8, though it did
turn up the project's second-best kernel (seed 3004, from the unbiased
side).
v0.2.4 documents the top matmul results as a showcase - see "Matrix
multiplication: the best kernels found so far" above - each with its full,
unedited in-world story, the assumption it broke, and what it became in C,
plus a generated hall-of-fame PNG (assets/flowchart/matmul_showcase.js,
make matmul-showcase) and an invent_pipeline flowchart embedded in the
README alongside the original run pipeline's. No code changes.
v0.2.5 adds the math itself: every showcased kernel's actual formula (same
O(n³) sum as the textbook algorithm, reordered for registers/cache - not a
different algorithm), plus Strassen's algorithm from the sister
matrixmultiply repo as the one place in the project the operation count
itself changes. No code changes.
v0.2.6 adds --assumption (pin assumption_focus for a batch instead of a
seeded draw across all 8 of matmul's silent assumptions) and wires it into
both immerse_prompt and bend_prompt - previously drawn but barely
used downstream, so pinning alone wouldn't have steered anything. Both
opt-in, byte-identical prompts when unset. Used it to steer a real batch
toward the byte/precision-level assumption - see "Fourth run" above:
steering worked 8/8, and 2/8 beat the one existing low-precision kernel
that's actually comparable, via a compensated float32-splitting idea
nobody named going in.
Release files for crazyai 0.2.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| crazyai-0.2.6.tar.gz | 167.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| crazyai-0.2.6-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 309.0 kB
Release files / crazyai-0.2.6.tar.gz
| Download URL | crazyai-0.2.6.tar.gz |
|---|---|
| Size | 167.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
599c59c0540e77d0c73a505ee4a4834201634f0558d650ca38b69f27cef3a96b
|
|
BLAKE2b-256 checksum How to use checksums |
5fde68e7a3498b0ba5f44b62d47b92be2960e894dbdef722fb4d0a7de1e70ef3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.10
|
Release files / crazyai-0.2.6-py3-none-any.whl
| Download URL | crazyai-0.2.6-py3-none-any.whl |
|---|---|
| Size | 141.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
55ad2962a584c9f3f0e5d50d96e122e75ceb53a662b1ee712a911e880ff87574
|
|
BLAKE2b-256 checksum How to use checksums |
4777777671a2deae9a3336e9c8e450738191f8c991637567c84b35c5b290cd62
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.10
|