[{"data":1,"prerenderedAt":700},["ShallowReactive",2],{"projects-teaser":3,"biography-milestones":485},[4,46,71,112,140,170,194,228,257,283,314,345,378,401,430,456],{"id":5,"title":6,"accent":7,"body":8,"commits":15,"date":22,"description":23,"emergent":24,"extension":25,"home":26,"langs":27,"meta":31,"navigation":32,"note":26,"path":33,"pushed":34,"repo":35,"seo":36,"shared":37,"skin":24,"spark":38,"spec":42,"stars":39,"stem":43,"url":44,"__hash__":45},"projects/projects/100year-archive.md","A century of objects","#7fe7ff",{"type":9,"value":10,"toc":11},"minimark",[],{"title":12,"searchDepth":13,"depth":13,"links":14},"",2,[],[16,19],{"date":17,"message":18},"26 Feb","Refactor SimilarObjects to streamline token management",{"date":20,"message":21},"25 Feb","refactor: enhance authentication token management and the UI","2025-03-28","An upload desk for a centenary archive: contributors add objects, the app surfaces ones that look like something already catalogued, and the token handling keeps a long cataloguing session from quietly dropping.","archive","md",null,[28,29,30],"Vue","TypeScript","CSS",{},true,"/projects/100year-archive","2026-02-26","johkirche/100year-object-upload-frontend",{"title":6,"description":23},false,[39,39,40,39,39,39,40,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,41,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39],0,1,3,"Directus · similar-object matching","projects/100year-archive","https://github.com/johkirche/100year-object-upload-frontend","DPUAgIWTrObQ7ftdc10IWt7TROpazu_tjXEk6nEN5yI",{"id":47,"title":48,"accent":49,"body":50,"commits":54,"date":55,"description":56,"emergent":57,"extension":25,"home":26,"langs":58,"meta":61,"navigation":32,"note":26,"path":62,"pushed":63,"repo":64,"seo":65,"shared":37,"skin":57,"spark":66,"spec":67,"stars":13,"stem":68,"url":69,"__hash__":70},"projects/projects/angry-birds-gan.md","Angry Birds levels, generated","#ff6b6b",{"type":9,"value":51,"toc":52},[],{"title":12,"searchDepth":13,"depth":13,"links":53},[],[],"2023-07-29","The published version: pretrained models plus the decoding algorithm, released alongside the paper “Utilizing GANs for Stable Structure Generation in Angry Birds”.","paper",[59,60],"Jupyter Notebook","Python",{},"/projects/angry-birds-gan","2025-02-18","Blaxzter/Utilizing-Generative-Adversarial-Networks-for-Stable-Structure-Generation-in-Angry-Birds",{"title":48,"description":56},[39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39],"paper · pretrained models","projects/angry-birds-gan","https://github.com/Blaxzter/Utilizing-Generative-Adversarial-Networks-for-Stable-Structure-Generation-in-Angry-Birds","6fCF9X1JP5_x8LPsn9WkTabfDvx9TSds1J1yIrtmpxo",{"id":72,"title":73,"accent":74,"body":75,"commits":79,"date":86,"description":87,"emergent":88,"extension":25,"home":89,"langs":90,"meta":92,"navigation":32,"note":26,"path":93,"pushed":94,"repo":95,"seo":96,"shared":32,"skin":97,"spark":98,"spec":107,"stars":108,"stem":109,"url":110,"__hash__":111},"projects/projects/episko.md","Episko","#00ff9c",{"type":9,"value":76,"toc":77},[],{"title":12,"searchDepth":13,"depth":13,"links":78},[],[80,83],{"date":81,"message":82},"18 Sep","fleet: rebuilt to the design, and it is the screen the app opens on",{"date":84,"message":85},"17 Sep","dashboard: three columns, one ranked queue, and a thread you can read","2026-07-16","A native cockpit for running a flock of coding agents at once. Every session gets a real terminal, and Claude and Codex stream back phase, context use, cost and permission prompts — so a dozen agents are as easy to mind as one chat.","sessions","https://episko.dev",[29,91,30],"Rust",{},"/projects/episko","2026-09-18","respeak-io/episko",{"title":73,"description":87},"cockpit",[39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,13,99,100,101,102,103,104,105,106,103],71,56,14,6,10,8,9,12,"Tauri + Rust · 198 of 617 commits",20,"projects/episko","https://github.com/respeak-io/episko","ouPWSvgfp3YItOvndfPCsi8vG3vtwkfXGmwesShuzvw",{"id":113,"title":114,"accent":115,"body":116,"commits":120,"date":125,"description":126,"emergent":127,"extension":25,"home":26,"langs":128,"meta":129,"navigation":32,"note":26,"path":130,"pushed":94,"repo":131,"seo":132,"shared":37,"skin":127,"spark":133,"spec":136,"stars":39,"stem":137,"url":138,"__hash__":139},"projects/projects/fabraham.md","This website","#9ad1ff",{"type":9,"value":117,"toc":118},[],{"title":12,"searchDepth":13,"depth":13,"links":119},[],[121,123],{"date":81,"message":122},"fix(explore): stop the hidden cards eating the free camera’s drag",{"date":81,"message":124},"feat(outro): the coda gets planets, and the finale lets the cursor go","2025-05-31","This site. Nuxt + Content, Lenis + GSAP, and a GLB head flown through an ASCII post-process — camera, lights, gaze and set-pieces all derived from a single scroll number.","ascii",[28,29,30],{},"/projects/fabraham","Blaxzter/fabraham",{"title":114,"description":126},[39,13,39,39,40,40,39,13,39,39,39,39,39,39,134,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,134,101,39,40,39,39,39,40,40,39,39,39,39,39,39,135],4,16,"one scroll signal · eight set-pieces","projects/fabraham","https://github.com/Blaxzter/fabraham","DDX7UZpq4DnAzXWCTBwlZY57ixKZ6uu18vLTgrn4hNY",{"id":141,"title":142,"accent":143,"body":144,"commits":148,"date":154,"description":155,"emergent":156,"extension":25,"home":26,"langs":157,"meta":158,"navigation":32,"note":26,"path":159,"pushed":160,"repo":161,"seo":162,"shared":37,"skin":163,"spark":164,"spec":166,"stars":39,"stem":167,"url":168,"__hash__":169},"projects/projects/free-fast-file-sync.md","Free Fast File Sync","#ff8a3d",{"type":9,"value":145,"toc":146},[],{"title":12,"searchDepth":13,"depth":13,"links":147},[],[149,152],{"date":150,"message":151},"24 Jul","fix(e2e-native): stop flaking on a slow msedgedriver startup (#4)",{"date":150,"message":153},"ci: make the Tier-2 native E2E actually run, and gate PRs with it (#3)","2026-06-25","File sync with a Rust core and a TypeScript shell. A native end-to-end suite gates every pull request — including the flaky slow-driver startup that used to break it.","files",[91,29,30],{},"/projects/free-fast-file-sync","2026-07-24","Blaxzter/Free-Fast-File-Sync",{"title":142,"description":155},"hatch",[39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,165,102,41,39,13,39,39,39,39,39,39,39,39],15,"Rust core · TS shell · Tier-2 E2E","projects/free-fast-file-sync","https://github.com/Blaxzter/Free-Fast-File-Sync","qwgGrQgusus3zcLhROFDNQRHWSvk_eOis7tjyiBNRyc",{"id":171,"title":172,"accent":115,"body":173,"commits":177,"date":178,"description":179,"emergent":180,"extension":25,"home":26,"langs":181,"meta":183,"navigation":32,"note":26,"path":184,"pushed":185,"repo":186,"seo":187,"shared":37,"skin":188,"spark":189,"spec":190,"stars":39,"stem":191,"url":192,"__hash__":193},"projects/projects/gaenapi.md","Genetic algorithms for the JVM",{"type":9,"value":174,"toc":175},[],{"title":12,"searchDepth":13,"depth":13,"links":176},[],[],"2020-02-27","Generic genetic-algorithm environments for the JVM — a hall of fame, selection-probability shaping, and automated hyper-parameter search.","dna",[182],"Java",{},"/projects/gaenapi","2025-12-19","Blaxzter/GaenAPI",{"title":172,"description":179},"genome",[39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39],"hall of fame · auto hyper-params","projects/gaenapi","https://github.com/Blaxzter/GaenAPI","lA2bR8q-KFP6JEuTLaT69S1WYnU03g1W94N31YEdOnU",{"id":195,"title":196,"accent":197,"body":198,"commits":202,"date":208,"description":209,"emergent":210,"extension":25,"home":26,"langs":211,"meta":212,"navigation":32,"note":26,"path":213,"pushed":214,"repo":215,"seo":216,"shared":37,"skin":217,"spark":218,"spec":224,"stars":39,"stem":225,"url":226,"__hash__":227},"projects/projects/gb-app-pwa.md","The hymnal you sing from","#ffd479",{"type":9,"value":199,"toc":200},[],{"title":12,"searchDepth":13,"depth":13,"links":201},[],[203,206],{"date":204,"message":205},"15 Sep","fix(lied): sound the note that was tapped",{"date":204,"message":207},"fix(noten): scale every note into the words’ width","2025-12-27","The hymnal people actually sing from: engraved music that re-breaks to the screen and keeps the words their room, notes you can tap to sound, and paging that follows the playlist or the order of service.","notes",[28,29,30],{},"/projects/gb-app-pwa","2026-09-19","johkirche/gb-app-pwa",{"title":196,"description":209},"staff",[39,39,39,39,39,39,39,39,39,39,39,39,39,39,13,40,219,101,219,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,165,105,41,39,39,39,39,39,39,39,39,220,221,222,39,39,223],7,5,62,32,33,"engraved notation · tap a note to hear it","projects/gb-app-pwa","https://github.com/johkirche/gb-app-pwa","KhMa8PxU3vEdNWNmpIla0NdHQs1YFf60XJLMBMyz6w4",{"id":229,"title":230,"accent":197,"body":231,"commits":235,"date":241,"description":242,"emergent":210,"extension":25,"home":26,"langs":243,"meta":246,"navigation":32,"note":26,"path":247,"pushed":214,"repo":248,"seo":249,"shared":37,"skin":250,"spark":251,"spec":253,"stars":40,"stem":254,"url":255,"__hash__":256},"projects/projects/gb-dashboard.md","The hymnal’s editing desk",{"type":9,"value":232,"toc":233},[],{"title":12,"searchDepth":13,"depth":13,"links":234},[],[236,239],{"date":237,"message":238},"4 Sep","refactor(inhaltsverzeichnis): Melodie-Spalte ohne 2000er-Liednummern",{"date":237,"message":240},"feat(noten): Choralbuchsatz im Notenbild-Karussell anzeigen","2024-02-15","The editing desk behind the church hymnal — table of contents, an engraved-music carousel and change notes. The congregation tells me on Sunday morning when it breaks.",[28,244,245],"JavaScript","SCSS",{},"/projects/gb-dashboard","Blaxzter/gb-dashboard",{"title":230,"description":242},"desk",[13,39,220,39,39,39,39,40,39,39,39,39,39,39,39,39,39,40,39,13,220,39,134,39,39,39,40,39,39,41,134,39,220,105,41,104,252,165,220,13,220,13,103,108,41,41,220,134,39,220,39,39],22,"Directus · Vue · Vuetify","projects/gb-dashboard","https://github.com/Blaxzter/gb-dashboard","g88Tl9Xlre1CR2rn_h0Pa3nHbP1Nxo3-aTM2UoOrisc",{"id":258,"title":259,"accent":197,"body":260,"commits":264,"date":269,"description":270,"emergent":271,"extension":25,"home":26,"langs":272,"meta":273,"navigation":32,"note":26,"path":274,"pushed":275,"repo":276,"seo":277,"shared":37,"skin":271,"spark":278,"spec":279,"stars":39,"stem":280,"url":281,"__hash__":282},"projects/projects/gb-pwa.md","The hymnal, offline",{"type":9,"value":261,"toc":262},[],{"title":12,"searchDepth":13,"depth":13,"links":263},[],[265,267],{"date":204,"message":266},"docs(testing): 887 tests across 27 files",{"date":204,"message":268},"fix(offline): honest download state, prompt-mode updates, install prompt","2025-06-06","The offline half of the hymnal — an honest download state, dark mode applied before the first paint, and a church-service stepper that locks while a service is actually running.","tests",[29,28,244],{},"/projects/gb-pwa","2026-09-15","johkirche/gb-pwa",{"title":259,"description":270},[39,39,39,39,39,39,39,39,39,39,39,220,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,13,220,134,39,39,39,39,39,39,39,108,41,40,39,39,39,101],"887 tests · 27 files · offline-first","projects/gb-pwa","https://github.com/johkirche/gb-pwa","UGXMY5Nc-9UwawQumINAiAnKZek6jIvllgltIRgkUd4",{"id":284,"title":285,"accent":286,"body":287,"commits":291,"date":298,"description":299,"emergent":300,"extension":25,"home":26,"langs":301,"meta":303,"navigation":32,"note":26,"path":304,"pushed":305,"repo":306,"seo":307,"shared":37,"skin":308,"spark":309,"spec":310,"stars":41,"stem":311,"url":312,"__hash__":313},"projects/projects/instant-twitch-replay.md","Instant Twitch Replay","#c4a0ff",{"type":9,"value":288,"toc":289},[],{"title":12,"searchDepth":13,"depth":13,"links":290},[],[292,295],{"date":293,"message":294},"22 Jul","feat: configurable replay volume and redesigned settings popup",{"date":296,"message":297},"22 Feb","feat: update version to 2.0 in manifest.json","2024-11-28","Records the last x seconds of a Twitch stream so you can replay the thing you just missed. Configurable replay volume, redesigned settings popup.","clips",[244,302],"HTML",{},"/projects/instant-twitch-replay","2026-07-22","Blaxzter/Instant-Twitch-Replay",{"title":285,"description":299},"scrub",[39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,134,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,13,39,39,39,39,39,39,39,39],"v2.0 · rolling 60s buffer","projects/instant-twitch-replay","https://github.com/Blaxzter/Instant-Twitch-Replay","WxFZVfTlTvFrB4p7UNLAs8cGqfXU4YK-q-iCr_Oa1IA",{"id":315,"title":316,"accent":317,"body":318,"commits":322,"date":329,"description":330,"emergent":331,"extension":25,"home":332,"langs":333,"meta":334,"navigation":32,"note":335,"path":336,"pushed":337,"repo":338,"seo":339,"shared":32,"skin":331,"spark":340,"spec":341,"stars":13,"stem":342,"url":343,"__hash__":344},"projects/projects/kitawo.md","Johannischer Kirchentag","#ffb454",{"type":9,"value":319,"toc":320},[],{"title":12,"searchDepth":13,"depth":13,"links":321},[],[323,326],{"date":324,"message":325},"Apr 2025","feat: fix filtering on preview page",{"date":327,"message":328},"Mar 2025","chore: update docker-compose and Dockerfile configurations","2020-07-04","The event site for the Johannischer Kirchentag — programme, dates and registration, baked to Cloudflare. Five years of on-and-off work with the community; I am its second-largest contributor.","event","https://johannischer-kirchentag.de",[28,244,29],{},"Nothing from me in this window — my 94 commits run Jun 2020 to Apr 2025. The site is live and others keep it moving.","/projects/kitawo","2026-08-21","johkirche/KiTaWo-Frontend",{"title":316,"description":330},[39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39],"johannischer-kirchentag.de · 94 commits","projects/kitawo","https://github.com/johkirche/KiTaWo-Frontend","9PbxgZ66bl9W7uxTXikLGL3WuWbcln_Ro_SiCJ1zlMA",{"id":346,"title":347,"accent":74,"body":348,"commits":352,"date":357,"description":358,"emergent":359,"extension":25,"home":360,"langs":361,"meta":362,"navigation":32,"note":26,"path":363,"pushed":214,"repo":364,"seo":365,"shared":37,"skin":366,"spark":367,"spec":374,"stars":39,"stem":375,"url":376,"__hash__":377},"projects/projects/logolab.md","LogoLab",{"type":9,"value":349,"toc":350},[],{"title":12,"searchDepth":13,"depth":13,"links":351},[],[353,355],{"date":81,"message":354},"feat(ui): ask what kind of report it is, then hand over a real GitHub form",{"date":81,"message":356},"fix(ui): a tooltip flips instead of landing on the control it describes","2026-06-09","Preview, clean up, vectorize and export your logo — 100% in your browser. No uploads, no sign-up. Background removal runs on WebGPU.","vectors","https://logolab.fabraham.dev",[29,302,30],{},"/projects/logolab","Blaxzter/LogoLab",{"title":347,"description":358},"alpha",[39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,106,368,165,134,220,369,370,104,371,372,105,165,13,373,370],43,21,17,23,13,52,"WebGPU · transformers.js · no upload","projects/logolab","https://github.com/Blaxzter/LogoLab","uOoVAnqqCPQA81ojFfYYw5bnp3zcZPZ8nthH7PpMWP8",{"id":379,"title":380,"accent":286,"body":381,"commits":385,"date":386,"description":387,"emergent":388,"extension":25,"home":26,"langs":389,"meta":390,"navigation":32,"note":26,"path":391,"pushed":392,"repo":393,"seo":394,"shared":37,"skin":395,"spark":396,"spec":397,"stars":40,"stem":398,"url":399,"__hash__":400},"projects/projects/master-thesis.md","The master’s thesis",{"type":9,"value":382,"toc":383},[],{"title":12,"searchDepth":13,"depth":13,"links":384},[],[],"2022-04-04","The thesis itself: GANs trained to invent Science Birds levels, scored on whether the structures they design actually stand up.","blocks",[59,60,182],{},"/projects/master-thesis","2022-12-10","Blaxzter/Master-Thesis_GAN-level-gen",{"title":380,"description":387},"lattice",[39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39],"Science Birds · playability-scored","projects/master-thesis","https://github.com/Blaxzter/Master-Thesis_GAN-level-gen","pe63VkNkG_q8mQfgpqOZvo7nb6tG2p3wy16oUTqpSfs",{"id":402,"title":403,"accent":7,"body":404,"commits":408,"date":414,"description":415,"emergent":416,"extension":25,"home":26,"langs":417,"meta":419,"navigation":32,"note":26,"path":420,"pushed":421,"repo":422,"seo":423,"shared":37,"skin":424,"spark":425,"spec":426,"stars":220,"stem":427,"url":428,"__hash__":429},"projects/projects/room-booking-tool.md","Room booking, self-hosted",{"type":9,"value":405,"toc":406},[],{"title":12,"searchDepth":13,"depth":13,"links":407},[],[409,412],{"date":410,"message":411},"17 Jun","chore: bake static-page content in Dockerfile.frontend build",{"date":410,"message":413},"feat: pre-render static-page content at build time (hybrid)","2024-04-02","Self-hostable room and resource booking. The static pages are pre-rendered at build time and baked straight into the frontend image.","rooms",[28,29,418],"Liquid",{},"/projects/room-booking-tool","2026-06-17","Blaxzter/room-booking-tool",{"title":403,"description":415},"week",[39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,40,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,220,39,39,39,39,39,39,39,39,39,39,39,39,39],"self-hosted · most-starred repo","projects/room-booking-tool","https://github.com/Blaxzter/room-booking-tool","4FkALikn0f89R24yXvvRL9vBh9nOVb0WtuqnnXH8d7U",{"id":431,"title":432,"accent":74,"body":433,"commits":437,"date":337,"description":443,"emergent":444,"extension":25,"home":445,"langs":446,"meta":447,"navigation":32,"note":26,"path":448,"pushed":94,"repo":449,"seo":450,"shared":37,"skin":444,"spark":451,"spec":452,"stars":39,"stem":453,"url":454,"__hash__":455},"projects/projects/speeden-and-cuben.md","Speeden & Cuben",{"type":9,"value":434,"toc":435},[],{"title":12,"searchDepth":13,"depth":13,"links":436},[],[438,440],{"date":81,"message":439},"Ask the question the other way round",{"date":441,"message":442},"16 Sep","Open a case in a cube you can turn yourself","A CFOP reference with live 3D playback — every algorithm machine-verified against a real cube model, and every case openable in a cube you can turn yourself.","cubes","https://speeden-and-cuben.fabraham.dev",[29,302,60],{},"/projects/speeden-and-cuben","Blaxzter/speeden-and-cuben",{"title":432,"description":443},[39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,219,219,39,220,134],"41 F2L · 57 OLL · 21 PLL","projects/speeden-and-cuben","https://github.com/Blaxzter/speeden-and-cuben","oaPSwtJCjl3Vo3ZZ60-h571nHpxVne1tNEEFLWJBvMI",{"id":457,"title":458,"accent":49,"body":459,"commits":463,"date":469,"description":470,"emergent":471,"extension":25,"home":26,"langs":472,"meta":473,"navigation":32,"note":26,"path":474,"pushed":475,"repo":476,"seo":477,"shared":37,"skin":478,"spark":479,"spec":481,"stars":39,"stem":482,"url":483,"__hash__":484},"projects/projects/wirksam.md","Wirksam",{"type":9,"value":460,"toc":461},[],{"title":12,"searchDepth":13,"depth":13,"links":462},[],[464,467],{"date":465,"message":466},"13 Sep","build(release): refuse to cut a release from the wrong branch",{"date":465,"message":468},"refactor(events): step through the copy wizard instead of stacking it","2026-03-03","An events tool in Python and Vue. No README yet — the commit log does the talking: a copy wizard you step through, and a release train that refuses to ship from the wrong branch.","tags",[60,28,29],{},"/projects/wirksam","2026-09-13","Blaxzter/wirksam",{"title":458,"description":470},"rail",[39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,134,40,220,41,219,165,135,222,371,134,480,370,370,105,106,39,39,39,39,39,39,39,39,39,39,39,108,369,104,40,368,219,41,105],29,"v0.20.1 · 306 commits / 52w","projects/wirksam","https://github.com/Blaxzter/wirksam","zvtGyc7Ie6FRt10j3LXkfKR8NgyZnyS2TBfKlLerHu8",[486,526,553,581,635,672],{"id":487,"title":488,"accent":115,"body":489,"description":12,"extension":25,"location":516,"meta":517,"navigation":32,"offset":26,"order":103,"path":518,"seo":519,"setPiece":520,"setPieceVariant":26,"side":522,"stem":523,"subtitle":524,"__hash__":525},"biography/biography/10-berlin.md","TU Berlin — B.Sc. Computer Science",{"type":9,"value":490,"toc":513},[491,496],[492,493,495],"h2",{"id":494},"tu-berlin-bsc","TU Berlin — B.Sc.",[497,498,499,500,504,505,508,509,512],"p",{},"Computer science at TU Berlin, finished at 1.8 — and the degree was the smaller\nhalf of it. At ",[501,502,503],"strong",{},"GT-ARC"," I worked on multi-agent systems; as a student developer\nat ",[501,506,507],{},"RWTH Aachen"," I helped build the identity-management apps behind\n~",[501,510,511],{},"47,000 students and 9,000 staff",". Systems that size are unforgiving about the\nunglamorous parts: migrations, permissions, and the Monday morning after a\nrelease.",{"title":12,"searchDepth":13,"depth":13,"links":514},[515],{"id":494,"depth":13,"text":495},"Berlin",{},"/biography/10-berlin",{"title":488,"description":12},[521],"berlinSkyline","auto","biography/10-berlin","2016–2020 · Berlin","9uDxoggfedQyGq8SX4xWBL09fbu6fx3ilwzBLEUim2U",{"id":527,"title":528,"accent":197,"body":529,"description":12,"extension":25,"location":544,"meta":545,"navigation":32,"offset":26,"order":108,"path":546,"seo":547,"setPiece":548,"setPieceVariant":26,"side":522,"stem":550,"subtitle":551,"__hash__":552},"biography/biography/20-the-move.md","The move",{"type":9,"value":530,"toc":541},[531,534],[492,532,528],{"id":533},"the-move",[497,535,536,537,540],{},"In 2020 I left Berlin for ",[501,538,539],{},"Maastricht"," and an M.Sc. in Artificial Intelligence.\nI had been using machine learning without properly understanding it, and wanted\ntwo years to fix that rather than keep reading about it on the side.",{"title":12,"searchDepth":13,"depth":13,"links":542},[543],{"id":533,"depth":13,"text":528},"En route",{},"/biography/20-the-move",{"title":528,"description":12},[549],"routeArc","biography/20-the-move","2020 · Berlin → Maastricht","3eL62aE9mg0_QhY9pMz6KOyLieNasaVCDr_6fwfxu8g",{"id":554,"title":555,"accent":286,"body":556,"description":12,"extension":25,"location":539,"meta":572,"navigation":32,"offset":26,"order":573,"path":574,"seo":575,"setPiece":576,"setPieceVariant":577,"side":522,"stem":578,"subtitle":579,"__hash__":580},"biography/biography/30-maastricht.md","Maastricht — M.Sc. Artificial Intelligence",{"type":9,"value":557,"toc":569},[558,562],[492,559,561],{"id":560},"maastricht-msc-ai","Maastricht — M.Sc. AI",[497,563,564,565,568],{},"M.Sc. Artificial Intelligence, GPA 8.25, specialising in generative models. My\n",[501,566,567],{},"thesis trained GANs to generate procedural game content"," — a network that\ninvents game levels, scored on whether the levels are actually playable. At the\ntime that was a research curiosity. It stopped being one about a year later.",{"title":12,"searchDepth":13,"depth":13,"links":570},[571],{"id":560,"depth":13,"text":561},{},30,"/biography/30-maastricht",{"title":555,"description":12},[395],"gan","biography/30-maastricht","2020–2022 · Maastricht","gHxy7geRtjtWmaz2Wh1Wo2lpaQ8Pz2-7wwIJVGH3oQc",{"id":582,"title":583,"accent":49,"body":584,"description":12,"extension":25,"location":516,"meta":625,"navigation":32,"offset":26,"order":626,"path":627,"seo":628,"setPiece":629,"setPieceVariant":631,"side":522,"stem":632,"subtitle":633,"__hash__":634},"biography/biography/40-tatort.md","Respeak — the Tatort game",{"type":9,"value":585,"toc":622},[586,590],[492,587,589],{"id":588},"tatort-at-scale","Tatort, at scale",[497,591,592,593,596,597,601,602,605,606,609,610,613,614,617,618,621],{},"Back in Berlin at ",[501,594,595],{},"Respeak",": a chat-based game tied to the TV series ",[598,599,600],"em",{},"Tatort",",\nwritten ",[501,603,604],{},"before ChatGPT"," and contracted to hold ",[501,607,608],{},"100k concurrent"," players. I\nowned the scaling work — an ",[501,611,612],{},"Azure migration",", ",[501,615,616],{},"sentence-embedding models on\nAzure ML",", a Flask refactor that cut redundant SQL and added caching, and load\nbalancing in front of it. It went live at ",[501,619,620],{},"18,000 concurrent",", built by a team\nof five.",{"title":12,"searchDepth":13,"depth":13,"links":623},[624],{"id":588,"depth":13,"text":589},{},40,"/biography/40-tatort",{"title":583,"description":12},[395,630],"threadBoard","embeddings","biography/40-tatort","2023 · 18,000 concurrent players","6LVASKZPfhln5mSIAUyAdPQokATIZ5UmOOV4rZGR6ww",{"id":636,"title":637,"accent":7,"body":638,"description":12,"extension":25,"location":516,"meta":662,"navigation":32,"offset":26,"order":663,"path":664,"seo":665,"setPiece":666,"setPieceVariant":668,"side":522,"stem":669,"subtitle":670,"__hash__":671},"biography/biography/50-experte.md","Experte — retrieval-augmented generation",{"type":9,"value":639,"toc":659},[640,644],[492,641,643],{"id":642},"experte-rag","Experte — RAG",[497,645,646,647,650,651,654,655,658],{},"I'm ",[501,648,649],{},"tech lead"," on Experte (respeak.io) and built its core: a ",[501,652,653],{},"RAG"," platform\nfor public administration that answers from an organisation's own documents —\nPDFs, SharePoint, Confluence — and ",[501,656,657],{},"cites"," each answer back to the page it came\nfrom. In that sector an answer nobody can check is worth nothing, so retrieval and\nprovenance are the product rather than a feature of it.",{"title":12,"searchDepth":13,"depth":13,"links":660},[661],{"id":642,"depth":13,"text":643},{},50,"/biography/50-experte",{"title":637,"description":12},[395,667],"documentGrid","rag","biography/50-experte","Respeak · tech lead","Rv155INkfdwmleJaYtiGgmvXwB2mgAN42abx6Ykhv2w",{"id":673,"title":674,"accent":197,"body":675,"description":12,"extension":25,"location":516,"meta":691,"navigation":32,"offset":26,"order":692,"path":693,"seo":694,"setPiece":695,"setPieceVariant":26,"side":522,"stem":697,"subtitle":698,"__hash__":699},"biography/biography/60-community.md","Gesangbuch PWA — volunteer work",{"type":9,"value":676,"toc":688},[677,681],[492,678,680],{"id":679},"community","Community",[497,682,683,684,687],{},"Away from paid work I maintain a ",[501,685,686],{},"Gesangbuch PWA"," for my church: a German\nhymnal as an offline-capable web app, in German and English, open source on\nGitHub. It has a congregation who will tell me on Sunday morning when it breaks,\nwhich is the shortest feedback loop I have anywhere.",{"title":12,"searchDepth":13,"depth":13,"links":689},[690],{"id":679,"depth":13,"text":680},{},60,"/biography/60-community",{"title":674,"description":12},[696],"staffLines","biography/60-community","Open source · for my church","481250Sm-9koAHrvqnh7u--DcOKLoaNXkqWQLDki7Ns",1790581192806]