[{"data":1,"prerenderedAt":593},["ShallowReactive",2],{"home-ru":3,"projects-ru":4,"posts-ru":349},null,[5,54,162,206],{"id":6,"title":7,"bars":8,"blurb":9,"body":10,"color":27,"contacts":3,"date":3,"dateModified":3,"description":28,"extension":29,"featured":30,"groups":3,"kicker":31,"meta":32,"metrics":33,"n":3,"navigation":43,"openTabs":3,"path":44,"progress":3,"readTime":3,"reading":3,"role":45,"rules":3,"running":3,"seo":46,"ships":3,"slug":47,"stack":3,"started":3,"status":3,"stem":48,"streak":3,"tag":49,"tagColor":3,"tagline":51,"tasks":3,"timeline":3,"topics":3,"week":3,"year":52,"__hash__":53},"ru\u002Fwork\u002Fcooking.md","…что-то новое",1,"заметочник для операторов небольших интернет-компаний. пока идея. тексты пока не продаются.",{"type":11,"value":12,"toc":22},"minimark",[13,16,19],[14,15,9],"p",{},[14,17,18],{},"пока только я. собрано ~10%, публичности 0%, инвесторов 0 (спасибо). если ведёшь небольшую интернет-компанию и постоянно теряешь из виду десять вещей, которые важны на следующей неделе, — напиши на \u002Fsignal, и я добавлю тебя в очень короткий бета-лист.",[14,20,21],{},"● черновик · тихий режим",{"title":23,"searchDepth":24,"depth":25,"links":26},"",2,3,[],"var(--fg-3)","тихий, ещё готовящийся заметочник для операторов небольших интернет-компаний. пока не продаётся.","md",false,"▸ CH.04 \u002F cooking · тихий режим",{},[34,37,40],[35,36],"прогресс","~10%",[38,39],"публично","нет",[41,42],"инвесторы","нет, спасибо",true,"\u002Fwork\u002Fcooking","пока только я",{"title":7,"description":28},"cooking","work\u002Fcooking",{"label":50,"color":27},"черновик","тихий режим","2026 → ?","5D-LHanSIl9tW43coH2erviq-8QonNqdTAP9AMQlAp8",{"id":55,"title":56,"bars":25,"blurb":57,"body":58,"color":140,"contacts":3,"date":3,"dateModified":3,"description":141,"extension":29,"featured":30,"groups":3,"kicker":142,"meta":143,"metrics":144,"n":3,"navigation":43,"openTabs":3,"path":153,"progress":3,"readTime":3,"reading":3,"role":154,"rules":3,"running":3,"seo":155,"ships":3,"slug":56,"stack":3,"started":3,"status":3,"stem":156,"streak":3,"tag":157,"tagColor":3,"tagline":159,"tasks":3,"timeline":3,"topics":3,"week":3,"year":160,"__hash__":161},"ru\u002Fwork\u002Fagent-monorepo.md","agent-monorepo","шаблон для команд, где большую часть кода пишут агенты. сначала контракты, потом люди, потом агенты.",{"type":11,"value":59,"toc":135},[60,64,67,70,73,77,80,119,122,132],[61,62,63],"h2",{"id":63},"цель",[14,65,66],{},"сделать так, чтобы в реальном продукте — бэкенд, веб, мобилка — большую часть кода мог безопасно и дёшево писать ai-агент, и при этом части не расходились молча.",[61,68,69],{"id":69},"проблема",[14,71,72],{},"агенты быстрые, но узко смотрят. они спокойно добавят поле в nest-контроллер и забудут про nuxt, переименуют flutter-модель и оставят серверную схему как есть. в обычном монорепо ничто их не останавливает — типы живут отдельно в каждом рантайме, и первая настоящая обратная связь — это 500-ка в проде.",[61,74,76],{"id":75},"как-решаем","как решаем",[14,78,79],{},"один контракт, три рантайма.",[81,82,83,91,97,111],"ul",{},[84,85,86,90],"li",{},[87,88,89],"strong",{},"openapi + asyncapi"," — единственный источник правды для запросов, событий и доменных моделей.",[84,92,93,96],{},[87,94,95],{},"кодген"," выдаёт типизированных клиентов и серверные заглушки для nest (typescript), nuxt (typescript) и flutter (dart) — изменение в спеке ломает компиляцию там, где это важно, до того как агент успеет отгрузить.",[84,98,99,102,103,106,107,110],{},[87,100,101],{},"prisma 7"," для данных, ",[87,104,105],{},"better auth"," для сессий, ",[87,108,109],{},"turbo + pnpm"," для склейки.",[84,112,113,114,118],{},"структура репо и readme написаны ",[115,116,117],"em",{},"под агентов",": маленькие понятные поверхности, чёткие границы «можно\u002Fнельзя», скрипты, которые агент реально умеет запускать.",[14,120,121],{},"сам шаблон специально маленький. идея не в «использовать этот фреймворк», а в «клонируй, выкинь лишнее, сохрани привычку писать через контракт».",[14,123,124,125],{},"исходники → ",[126,127,131],"a",{"href":128,"rel":129},"https:\u002F\u002Fgithub.com\u002Fevgentus-cy\u002Fclaude-driven-nest-nuxt-flutter-monorepo",[130],"nofollow","github.com\u002Fevgentus-cy\u002Fclaude-driven-nest-nuxt-flutter-monorepo",[14,133,134],{},"● oss · инструмент · mit",{"title":23,"searchDepth":24,"depth":25,"links":136},[137,138,139],{"id":63,"depth":24,"text":63},{"id":69,"depth":24,"text":69},{"id":75,"depth":24,"text":76},"var(--green)","agent-monorepo — spec-first шаблон для ai-команд, склеивающий nestjs, nuxt и flutter вокруг общего openapi + asyncapi-контракта.","▸ ГЛ.04 \u002F agent-monorepo · oss-инструмент",{},[145,148,150],[146,147],"рантаймы","nest · nuxt · flutter",[149,89],"контракты",[151,152],"лицензия","mit","\u002Fwork\u002Fagent-monorepo","автор · мейнтейнер",{"title":56,"description":141},"work\u002Fagent-monorepo",{"label":158,"color":140},"oss · инструмент","spec-first монорепо для ai-команд","2025 → сейчас","uIgN3l8dQr1zre_BB1dWvpjgjmusctzBCqYH6iAKiOM",{"id":163,"title":164,"bars":165,"blurb":166,"body":167,"color":182,"contacts":3,"date":3,"dateModified":3,"description":183,"extension":29,"featured":30,"groups":3,"kicker":184,"meta":185,"metrics":186,"n":3,"navigation":43,"openTabs":3,"path":196,"progress":3,"readTime":3,"reading":3,"role":197,"rules":3,"running":3,"seo":198,"ships":3,"slug":199,"stack":3,"started":3,"status":3,"stem":200,"streak":3,"tag":201,"tagColor":3,"tagline":203,"tasks":3,"timeline":3,"topics":3,"week":3,"year":204,"__hash__":205},"ru\u002Fwork\u002Fkind.md","kind.events",5,"спокойная карта того, что происходит в эти выходные. с кураторством, без платных размещений, без шума.",{"type":11,"value":168,"toc":180},[169,171,174,177],[14,170,166],{},[14,172,173],{},"делаем с другом с 2024 года, растём медленно и специально. 320 событий в месяц, три города, лист ожидания на 2.4k человек, которые хотят видеть свой город в списке.",[14,175,176],{},"сейчас отгружаю v2 — календарное представление, имейл-дайджесты и более чистая карта.",[14,178,179],{},"● для людей · афиша событий · кипр",{"title":23,"searchDepth":24,"depth":25,"links":181},[],"var(--amber)","kind.events — спокойная кураторская карта того, что происходит в эти выходные в трёх кипрских городах. без платных размещений, без шума.","▸ CH.04 \u002F kind · недавний запуск",{},[187,190,193],[188,189],"событий","320\u002Fмес",[191,192],"городов","3",[194,195],"в листе ожидания","2.4k","\u002Fwork\u002Fkind","соло + 1 друг",{"title":164,"description":183},"kind","work\u002Fkind",{"label":202,"color":182},"для людей","афиша событий · кипр","2024 → сейчас","yh7NnEWfxpkrJREOAHeAicD2zevGqb_MdxQBTPExpU0",{"id":207,"title":208,"bars":209,"blurb":210,"body":211,"color":325,"contacts":3,"date":3,"dateModified":3,"description":326,"extension":29,"featured":43,"groups":3,"kicker":327,"meta":328,"metrics":329,"n":3,"navigation":43,"openTabs":3,"path":339,"progress":3,"readTime":3,"reading":3,"role":340,"rules":3,"running":3,"seo":341,"ships":3,"slug":342,"stack":3,"started":3,"status":3,"stem":343,"streak":3,"tag":344,"tagColor":3,"tagline":346,"tasks":3,"timeline":3,"topics":3,"week":3,"year":347,"__hash__":348},"ru\u002Fwork\u002Fmatchpro.md","matchpro.io",4,"нишевый джоб-борд, который действительно матчит людей, а не ключевые слова. этой весной переписал матчинговый движок.",{"type":11,"value":212,"toc":319},[213,216,224,227,230,240,243,247,274,276,280,306,316],[14,214,215],{},"¶ кейс — 01 · отгружено весна '26 · срок: 11 недель · команда: 1\nтеги: matching · search · postgres",[61,217,219,220,223],{"id":218},"старый-движок-матчил-по-ключевикам-новый-читает-всё-резюме-целиком","старый движок матчил по ",[115,221,222],{},"ключевикам",". новый — читает всё резюме целиком.",[14,225,226],{},"автор: евгений · 18 апр 2026 · ~8 мин чтения",[14,228,229],{},"три года matchpro матчил кандидатов с вакансиями по-ленивому — tf-idf по заголовкам с щепоткой правил. было нормально. не отлично. рекрутеры продолжали присылать мне скриншоты очевидных матчей, которые движок не находил. этой весной я сел и переписал всё целиком.",[231,232,233],"blockquote",{},[14,234,235,236,239],{},"«матчинг — это не поиск. поиск вознаграждает точность. матчинг вознаграждает ",[115,237,238],{},"интересную близость",".»",[241,242],"hr",{},[61,244,246],{"id":245},"как-это-происходило","как это происходило",[248,249,250,256,262,268],"ol",{},[84,251,252,255],{},[87,253,254],{},"выкинуть ранкер"," — данные оставил, модель удалил. начал с пустого ipynb.",[84,257,258,261],{},[87,259,260],{},"эмбеддить всё"," — резюме + текст вакансии → небольшая мультиязычная модель, кэш в pg_vector.",[84,263,264,267],{},[87,265,266],{},"пере-ранжировать по сигналам"," — локация, сениорити, годы в стеке. скучные фичи всё ещё побеждают.",[84,269,270,273],{},[87,271,272],{},"тень-прогон 3 недели"," — a\u002Fb по кликам рекрутеров. смотрел на дашборды больше, чем на семью.",[241,275],{},[61,277,279],{"id":278},"результаты-через-11-недель","результаты — через 11 недель",[81,281,282,288,294,300],{},[84,283,284,287],{},[87,285,286],{},"качество матча (рекрутер 👍)"," — 41% → 78% (+37 пп)",[84,289,290,293],{},[87,291,292],{},"время до первого клика"," — 9.2с → 3.1с (−6.1с)",[84,295,296,299],{},[87,297,298],{},"трудоустройств в неделю"," — 12 → 28 (×2.3)",[84,301,302,305],{},[87,303,304],{},"latency (p95)"," — 640мс → 180мс (−72%)",[307,308,313],"pre",{"className":309,"code":311,"language":312},[310],"language-text","› bench --cohort=q1-recruiters\n  running 2,140 matches…\n  ✓ v3 beats v2 on 78% of pairs\n  ! 4 regressions — investigating\n› deploy prod\n","text",[314,315,311],"code",{"__ignoreMap":23},[14,317,318],{},"● опубликовано · 41kb · 2 графика · 6 сносок",{"title":23,"searchDepth":24,"depth":25,"links":320},[321,323,324],{"id":218,"depth":24,"text":322},"старый движок матчил по ключевикам. новый — читает всё резюме целиком.",{"id":245,"depth":24,"text":246},{"id":278,"depth":24,"text":279},"var(--red)","matchpro.io — нишевый кипрский джоб-борд, который матчит людей, а не ключевики. весной '26 переписал матчинговый движок.","▸ CH.04 \u002F matchpro · сейчас отгружаю v3",{},[330,333,336],[331,332],"вакансий","1.2k\u002Fмес",[334,335],"трудоустройств","~180",[337,338],"выручка","в плюсе","\u002Fwork\u002Fmatchpro","соло · дизайн + код + операции",{"title":208,"description":326},"matchpro","work\u002Fmatchpro",{"label":345,"color":325},"в центре","джоб-борд · it · кипр","2021 → сейчас","0p8ess8BgWeP9r-sRX9cAQjJnDEcrMf91zGfZzEQWZw",[350,416,459,501,553],{"id":351,"title":352,"bars":3,"blurb":353,"body":354,"color":3,"contacts":3,"date":403,"dateModified":3,"description":404,"extension":29,"featured":43,"groups":3,"kicker":405,"meta":406,"metrics":3,"n":407,"navigation":43,"openTabs":3,"path":408,"progress":3,"readTime":409,"reading":3,"role":3,"rules":3,"running":3,"seo":410,"ships":3,"slug":411,"stack":3,"started":3,"status":3,"stem":412,"streak":3,"tag":413,"tagColor":325,"tagline":3,"tasks":3,"timeline":3,"topics":3,"week":3,"year":3,"__hash__":415},"ru\u002Fwriting\u002F014-matchpro-engine.md","Как я переписывал матчинговый движок matchpro","Что я понял, три недели наблюдая за кликами рекрутеров.",{"type":11,"value":355,"toc":400},[356,359,362,366,368,370,376,394,397],[14,357,358],{},"▸ в центре · кейс — № 014 · 18 апр '26 · 8 мин",[61,360,352],{"id":361},"как-я-переписывал-матчинговый-движок-matchpro",[14,363,364],{},[115,365,353],{},[241,367],{},[14,369,229],{},[231,371,372],{},[14,373,235,374,239],{},[115,375,238],{},[248,377,378,382,386,390],{},[84,379,380,255],{},[87,381,254],{},[84,383,384,261],{},[87,385,260],{},[84,387,388,267],{},[87,389,266],{},[84,391,392,273],{},[87,393,272],{},[14,395,396],{},"цифры через 11 недель: качество матча 41% → 78%, время до первого клика 9.2с → 3.1с, трудоустройств в неделю 12 → 28, p95 latency 640мс → 180мс.",[14,398,399],{},"полный разбор — в \u002Fwork\u002Fmatchpro.",{"title":23,"searchDepth":24,"depth":25,"links":401},[402],{"id":361,"depth":24,"text":352},"2026-04-18","Как я переписывал матчинговый движок matchpro — что я понял, три недели наблюдая за кликами рекрутеров.","кейс",{},"014","\u002Fwriting\u002F014-matchpro-engine","8 мин",{"title":352,"description":404},"014-matchpro-engine","writing\u002F014-matchpro-engine",{"label":414,"color":325},"длинный текст","Y1a_qRsAGhXruSGRgEhmMmNqiGbKNSA3DLxb_8ebrrs",{"id":417,"title":418,"bars":3,"blurb":419,"body":420,"color":3,"contacts":3,"date":446,"dateModified":3,"description":447,"extension":29,"featured":30,"groups":3,"kicker":448,"meta":449,"metrics":3,"n":450,"navigation":43,"openTabs":3,"path":451,"progress":3,"readTime":452,"reading":3,"role":3,"rules":3,"running":3,"seo":453,"ships":3,"slug":454,"stack":3,"started":3,"status":3,"stem":455,"streak":3,"tag":456,"tagColor":182,"tagline":3,"tasks":3,"timeline":3,"topics":3,"week":3,"year":3,"__hash__":458},"ru\u002Fwriting\u002F013-support-email.md","Почему я до сих пор отвечаю на каждое письмо в поддержку сам","Короткая защита того, что поддержку стоит делать осознанно.",{"type":11,"value":421,"toc":443},[422,425,428,432,434,437,440],[14,423,424],{},"№ 013 · 02 апр '26 · 4 мин · операции",[61,426,418],{"id":427},"почему-я-до-сих-пор-отвечаю-на-каждое-письмо-в-поддержку-сам",[14,429,430],{},[115,431,419],{},[241,433],{},[14,435,436],{},"каждый ответ уходит под моим именем. не общий ящик, не скрипт первой линии, не чат-бот с улыбающимся аватаром.",[14,438,439],{},"мне говорят, что это не масштабируется. правы — не масштабируется. в этом и смысл. поддержка — это место, где выясняется, какие из твоих умных фич ломаются во вторник утром у реального человека в реальном часовом поясе. я лучше прочитаю эти письма сам, чем еженедельный дайджест.",[14,441,442],{},"группа маленькая — осознанно. инбокс фаундера — это ров, а не статья расходов.",{"title":23,"searchDepth":24,"depth":25,"links":444},[445],{"id":427,"depth":24,"text":418},"2026-04-02","Почему я до сих пор отвечаю на каждое письмо в поддержку сам — короткая защита того, что поддержку стоит делать осознанно.","операции",{},"013","\u002Fwriting\u002F013-support-email","4 мин",{"title":418,"description":447},"013-support-email","writing\u002F013-support-email",{"label":457,"color":182},"блокнот","gahZ-O8cCmlAdSS4aafxyn_l7SLufaxkgd5aNDqyvkI",{"id":460,"title":461,"bars":3,"blurb":462,"body":463,"color":3,"contacts":3,"date":489,"dateModified":3,"description":490,"extension":29,"featured":30,"groups":3,"kicker":491,"meta":492,"metrics":3,"n":493,"navigation":43,"openTabs":3,"path":494,"progress":3,"readTime":495,"reading":3,"role":3,"rules":3,"running":3,"seo":496,"ships":3,"slug":497,"stack":3,"started":3,"status":3,"stem":498,"streak":3,"tag":499,"tagColor":182,"tagline":3,"tasks":3,"timeline":3,"topics":3,"week":3,"year":3,"__hash__":500},"ru\u002Fwriting\u002F012-shipping-silently.md","Как отгружать, когда никто не смотрит","Уведомления в Slack выключены. Клавиатура включена. Доверяй календарю.",{"type":11,"value":464,"toc":486},[465,468,471,475,477,480,483],[14,466,467],{},"№ 012 · 20 мар '26 · 3 мин · процесс",[61,469,461],{"id":470},"как-отгружать-когда-никто-не-смотрит",[14,472,473],{},[115,474,462],{},[241,476],{},[14,478,479],{},"в большинстве недель ничего драматичного не происходит. бэкенд-миграция выкатывается. опечатка исправляется. маленькая фича уходит за флагом к одиннадцати пользователям.",[14,481,482],{},"соблазнительно ждать аудиторию, прежде чем что-то делать. привязывать каждый релиз к лонч-твиту, рассылке, посту. тихие недели — это ровно те недели, в которые продукты на самом деле собираются.",[14,484,485],{},"календарь говорит отгружать в пятницу. значит, отгружаешь в пятницу.",{"title":23,"searchDepth":24,"depth":25,"links":487},[488],{"id":470,"depth":24,"text":461},"2026-03-20","Как отгружать, когда никто не смотрит — slack выключен, клавиатура включена, доверяй календарю.","процесс",{},"012","\u002Fwriting\u002F012-shipping-silently","3 мин",{"title":461,"description":490},"012-shipping-silently","writing\u002F012-shipping-silently",{"label":457,"color":182},"Tse6Eqxwg-drUY-h1fHYl2Y2hgYgTvcqlWCx3u64OMg",{"id":502,"title":503,"bars":3,"blurb":504,"body":505,"color":3,"contacts":3,"date":540,"dateModified":3,"description":541,"extension":29,"featured":30,"groups":3,"kicker":542,"meta":543,"metrics":3,"n":544,"navigation":43,"openTabs":3,"path":545,"progress":3,"readTime":546,"reading":3,"role":3,"rules":3,"running":3,"seo":547,"ships":3,"slug":548,"stack":3,"started":3,"status":3,"stem":549,"streak":3,"tag":550,"tagColor":140,"tagline":3,"tasks":3,"timeline":3,"topics":3,"week":3,"year":3,"__hash__":552},"ru\u002Fwriting\u002F011-postgres-only.md","Странные радости бэкенда только на postgres","Что происходит, если пять лет отказываться добавлять вторую базу.",{"type":11,"value":506,"toc":537},[507,510,513,517,519,534],[14,508,509],{},"№ 011 · 06 мар '26 · 6 мин · стек",[61,511,503],{"id":512},"странные-радости-бэкенда-только-на-postgres",[14,514,515],{},[115,516,504],{},[241,518],{},[14,520,521,522,525,526,529,530,533],{},"правило простое: если postgres умеет — делаем в postgres. очередь задач? ",[314,523,524],{},"SELECT ... FOR UPDATE SKIP LOCKED",". полнотекстовый поиск? ",[314,527,528],{},"tsvector",". векторный поиск? ",[314,531,532],{},"pg_vector",". кэширование? материализованные вьюхи и крон. фиче-флаги? таблица.",[14,535,536],{},"звучит аскетично. так и есть. а ещё это пять лет, в которые меньше движущихся частей, одна история про бэкапы, один дашборд мониторинга, одна ментальная модель. в день, когда придётся добавить redis, я напишу по этому поводу грустную заметку. этот день ещё не наступил.",{"title":23,"searchDepth":24,"depth":25,"links":538},[539],{"id":512,"depth":24,"text":503},"2026-03-06","Странные радости бэкенда только на postgres — что происходит, если пять лет отказываться добавлять вторую базу.","стек",{},"011","\u002Fwriting\u002F011-postgres-only","6 мин",{"title":503,"description":541},"011-postgres-only","writing\u002F011-postgres-only",{"label":551,"color":140},"техническое","rDdWRSu_UEm7uBwD9-j5OMpa1Voasp_45fWBKqoF7mg",{"id":554,"title":555,"bars":3,"blurb":556,"body":557,"color":3,"contacts":3,"date":580,"dateModified":3,"description":581,"extension":29,"featured":30,"groups":3,"kicker":582,"meta":583,"metrics":3,"n":584,"navigation":43,"openTabs":3,"path":585,"progress":3,"readTime":586,"reading":3,"role":3,"rules":3,"running":3,"seo":587,"ships":3,"slug":588,"stack":3,"started":3,"status":3,"stem":589,"streak":3,"tag":590,"tagColor":591,"tagline":3,"tasks":3,"timeline":3,"topics":3,"week":3,"year":3,"__hash__":592},"ru\u002Fwriting\u002F010-year-limassol.md","Год утров в Лимассоле","Двенадцать месяцев письма в 6 утра, прогулок под рожковыми деревьями и один сломанный чайник.",{"type":11,"value":558,"toc":577},[559,562,565,569,571,574],[14,560,561],{},"№ 010 · 22 фев '26 · 5 мин · жизнь",[61,563,555],{"id":564},"год-утров-в-лимассоле",[14,566,567],{},[115,568,556],{},[241,570],{},[14,572,573],{},"свет здесь приходит рано и дёшево. я начал вставать в шесть, писать час, идти двенадцать минут к морю раньше, чем остальные берут в руки телефон.",[14,575,576],{},"через двенадцать месяцев рутина всё ещё рутина. чайник сломался в ноябре. рожковые деревья на месте. тексты в основном лучше. свет по-прежнему — лучшее, что есть на кипре.",{"title":23,"searchDepth":24,"depth":25,"links":578},[579],{"id":564,"depth":24,"text":555},"2026-02-22","Год утров в Лимассоле — двенадцать месяцев письма в 6 утра, прогулок под рожковыми деревьями и один сломанный чайник.","жизнь",{},"010","\u002Fwriting\u002F010-year-limassol","5 мин",{"title":555,"description":581},"010-year-limassol","writing\u002F010-year-limassol",{"label":582,"color":591},"var(--fg-2)","Z1cPnE_I5j95WaOse5YMmnK1KDLPv9JIKgO3Y202YQs",1777071043154]