waliori
Layer
TabBWLDQZOY,KBkspShiftCSNTV.AEIHAltEscPGRMJ'X-UFShiftCtrltap: accentNAVholdSpaceEnterSYMholdSuper
Letters placed by annealing on 1.68 million characters of my writing. The dark keys spell the name, hands alternating; the orange keys lead to a layer.
1234567890BkspSuperAltCtrlShift←↓↑→DelStudioHomePgDnPgUpEndCaps W
Hold the left middle thumb. Digits on the top row, arrows under the right home row, modifiers under the left.
!@#$%^&*()Bksp":()?-=[]\;/<>|_+{}`
Hold the right middle thumb. Punctuation and brackets without Shift, pairs side by side.
BOOTF7F8F9F12Vol−MuteVol+PlayNextRESETF4F5F6F11BT0BT1BT2BT3BT4GAMEholdF1F2F3F10BT clrUSB/BLEBri−Bri+
Hold both middle thumbs. Bluetooth profiles, function keys, media, bootloader and reset, and the GAME toggle.
ôçàéîùCtrltap again
Tap Ctrl once, then the letter: é à ù î ô ç. Tap twice for è â û ï, three times for ê ü, four for ë.
TabQWER1YUIOPBkspShiftASDF2HJKL;AltCtrlZXCV3NM,./Esc4Space5EnterSYMholdSuper
Plain QWERTY, locked with ADJ and the bottom-left letter key. No hold layers, so nothing fires by accident mid-fight.

A layout annealed on my own words

The Walid letters, ten ZMK layers, a trainer for my weak keys.

Thirty letters, one run of annealing

The method is five steps down.

65 / 33 / 2

English, French, Darija: how the corpus was weighted.

The name on the board

wleftarightlleftirightdleft

Walid’s Annealed Layout with International Dead-keys. The five keys sit dark on the board above, and every letter changes hand.

Accents by count

Tapseauioc
1éàùîôç
2èâûï
3êü
4ë

One Ctrl tap per accent, then the letter. The OS runs US International.

How the letters were chosen

Five steps, every number from the scripts in the repository.

  1. 1Measure what I type

    Every message I ever typed to an AI: the Claude Code history and the claude.ai export. Pasted text, code, URLs and logs thrown out, duplicates removed, each message tagged by its stop words. 1,677,299 characters remained.

    I weighted French up to a third of the mix, because my work writing is French and none of it was in the sample.

    e13.0%t9.1%a8.0%o7.3%i7.0%n6.5%s6.5%r5.5%

    The eight letters I type most, and their share of every keystroke.

  2. 2Price every key

    The geometry is beekeeb’s own firmware file: the column stagger, the finger that owns each column, each finger’s home key. A key costs one plus its distance from home, times 1.6 under a pinky, 1.2 under a ring finger, 1.3 on the inner index columns.

    Home keys cost 1. The far corners cost 3.2.

    3.22.4223.033.03222.43.21.61.2112.612.61111.21.63.22.4223.253.25222.43.2

    The cost of each of the thirty core keys. Darker is dearer.

  3. 3Define the score

    Lower is better: each term is a share of my letter pairs or triples, times a weight I picked. Other weights give another board; a first run without finger caps put 16% on each ring finger. That caveat is the method.

    TermCountsWeightPoints
    Same-finger bigramsone finger, twice3.04.18
    Same-finger skipgramsone letter between0.85.28
    Scissorstwo rows apart1.50.66
    Lateral stretchesinner column1.00.51
    Redirectsone hand, a turn1.2 + 2.03.76
    Rolls, in and outcredited−0.12, −0.05−2.47
    Travelcost map, weighted8.013.02
    Loadpinky, balance, caps1.0, 0.5, 1.50.61
    Score25.54

    Points = share × weight × 100: 1.39% on one finger × 3 = 4.18. They add up to the score.

  4. 4Search by annealing

    Start from a random board. Swap two keys, score again. Better: keep it. Worse: keep it with a probability that falls as the run cools.

    Below, seed 5’s run, 132 down to 25.5. Early, one swap in six is kept although it hurts; late, none. Eight runs scored 480,000 of the 30! boards, 2.65 × 1032.

    2550751001250k315k0.8630k0.2445k0.0760k0.02 scoreswapstemp. current boardbest, 25.54

    current boardbest so far

  5. 5Pick, and say why

    Three seeds tied within five thousandths. Seed 1 mirrors seed 5, so the vowels went right, the convention.

    Seed 0 scores 0.005 better but has r on the home key where seed 5 has n, typed a fifth more often.

    Graphite was the recommendation. I wanted mine.

    1. vblmqzoy,kcsrtw.aeihpgndj'x-ufSeed 025.537 apart
    2. k,yozqdlwbhiea.vtnscfu-x'jmrgpSeed 125.54the mirror
    3. bwldqzoy,kcsntv.aeihpgrmj'x-ufSeed 525.54the pick
    4. bu-x'qmrgwhieazvtnsck,yo.jdlfpSeed 725.6318 apart, mirrored
    5. k'fo,qmrgvuiea.wtnsphy-xzjdlcbSeed 325.7717 apart, mirrored
    6. k,x-qjdlwbhiae.vtnscfuoy'zmrgpSeed 625.919 apart, mirrored
    7. zjmpv-f,.knrtsw'eoihbldcgqyauxSeed 425.9726 apart
    8. k,.yqwpdlbhiae-gtsrnxuof'vmcjzSeed 226.1821 apart, mirrored

    Left hand then right; orange, the keys that differ from the pick or, when nearer, from its mirror.

    Seed 0Seed 5
    Score25.53325.538
    Same-finger bigrams1.39%1.35%
    Home row58.3%58.7%
    Travel1.6361.627

The corpus stays private, the scripts do not. The final run:

TAG=_v2 python3 optimize2.py free 8 60000

Measured against the layouts I almost chose

Same corpus, same analyzer; lower is better, except home row.

Colemak-DH wins the home row and the travel, then loses everything two letters long: half again as many same-finger bigrams, five times the lateral stretches, twice the redirects. The score is the step 3 formula, the search’s own compass, so it favours Walid by construction; the shares are the fair test.

LayoutSame-finger bigramsSkipgramsRedirectsLateral stretchesScissorsHome rowTravelScore
QWERTY6.63%7.82%6.93%7.21%5.38%31.0%2.12979.45
Colemak-DH2.14%6.42%6.39%2.54%0.18%68.0%1.57442.53
Graphite1.73%4.18%2.06%1.31%1.00%62.5%1.63240.46
Ergo-L1.33%5.89%6.30%3.32%0.65%65.4%1.63743.63
Walid1.35%4.58%2.80%0.50%0.43%58.7%1.62725.54

A semicolon or slash key is counted as the punctuation it replaces.

Two halves, no dongle

ZMK v0.3, built with Nix.

Left half

Central
the right half and the host, USB or five Bluetooth profiles
Compiler
GCC 12; GCC 15 dropped the link
Flashing notes

Right half

Peripheral
its keys go to the left half over Bluetooth
Keymap
none of its own, so it is never reflashed
Its config

Prospector

Role
a status screen on the left half’s advertisement
Shows
layer, both batteries, modifiers, profile
Scanner source
The trainer: lesson 1 of 10, the warm-up letters, the next key marked on the board with the finger to use
The trainer in Chunks mode: six letter groups, each three times alone then inside two words
The trainer settings: keyboard hints, target speed slider, sync between devices, live feed
The trainer statistics on 29 October: 131 texts, 2 h 32 m practised, 15 wpm over the last ten texts, best 30, 4 of 26 keys at target, speed text by text, stars per lesson

A trainer that knows which keys lag

Speed times accuracy opens the next lesson

Each key holds a confidence against the target; the lesson opens when its new keys turn green.

Chunks and weak pairs

Letter groups from my own word lists and my slow pairs return until they stop being slow.

The board mirrors the USB key presses

A serial feed from the left half lights the real key; progress follows a secret code between machines.

My own numbers, eleven days in

131 texts, 2 h 32 m, 30 wpm at best, 4 keys of 26 at target. Each dot a text, the line the last ten.

Learn it on the keyboard you have

The trainer runs in any browser, Walid or QWERTY.

The trainer statistics, Keys tab: the board coloured by mastery, green at target, red new, and the weakest keys listed with their speed and accuracy