<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Pet-Projects on Alexey Panfilov — Product, AI, Systems</title><link>https://dzarlax.dev/ru/tags/pet-projects/</link><description>Recent content in Pet-Projects on Alexey Panfilov — Product, AI, Systems</description><generator>Hugo</generator><language>ru</language><lastBuildDate>Sat, 23 May 2026 14:19:10 +0200</lastBuildDate><atom:link href="https://dzarlax.dev/ru/tags/pet-projects/index.xml" rel="self" type="application/rss+xml"/><item><title>Я пытался сделать переводчик для блога. В итоге сделал QA-обвязку.</title><link>https://dzarlax.dev/ru/articles/%D1%8F-%D0%BF%D1%8B%D1%82%D0%B0%D0%BB%D1%81%D1%8F-%D1%81%D0%B4%D0%B5%D0%BB%D0%B0%D1%82%D1%8C-%D0%BF%D0%B5%D1%80%D0%B5%D0%B2%D0%BE%D0%B4%D1%87%D0%B8%D0%BA-%D0%B4%D0%BB%D1%8F-%D0%B1%D0%BB%D0%BE%D0%B3%D0%B0.-%D0%B2-%D0%B8%D1%82%D0%BE%D0%B3%D0%B5-%D1%81%D0%B4%D0%B5%D0%BB%D0%B0%D0%BB-qa-%D0%BE%D0%B1%D0%B2%D1%8F%D0%B7%D0%BA%D1%83./</link><pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate><guid>https://dzarlax.dev/ru/articles/%D1%8F-%D0%BF%D1%8B%D1%82%D0%B0%D0%BB%D1%81%D1%8F-%D1%81%D0%B4%D0%B5%D0%BB%D0%B0%D1%82%D1%8C-%D0%BF%D0%B5%D1%80%D0%B5%D0%B2%D0%BE%D0%B4%D1%87%D0%B8%D0%BA-%D0%B4%D0%BB%D1%8F-%D0%B1%D0%BB%D0%BE%D0%B3%D0%B0.-%D0%B2-%D0%B8%D1%82%D0%BE%D0%B3%D0%B5-%D1%81%D0%B4%D0%B5%D0%BB%D0%B0%D0%BB-qa-%D0%BE%D0%B1%D0%B2%D1%8F%D0%B7%D0%BA%D1%83./</guid><description>&lt;p&gt;Я начал с простого желания: у меня были английские статьи на dzarlax.dev, и я хотел получить их русские и сербские версии, не превращая каждую публикацию в проект на выходные.&lt;/p&gt;
&lt;p&gt;На первый взгляд всё выглядело автоматизируемым. Исходник — в Markdown. На сайте уже настроена мультиязычная маршрутизация. Текст я пишу в Obsidian vault, а структура статей максимально предсказуема:&lt;/p&gt;
&lt;p&gt;Plaintext&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;articles/&amp;lt;slug&amp;gt;/index.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;articles/&amp;lt;slug&amp;gt;/index.ru.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;articles/&amp;lt;slug&amp;gt;/index.rs.md
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Поэтому изначальный вопрос казался чисто техническим: какую модель перевода выбрать?&lt;/p&gt;</description></item><item><title>Health Dashboard, часть 3: мои носимые устройства лгали по умолчанию</title><link>https://dzarlax.dev/ru/articles/health-dashboard-%D1%87%D0%B0%D1%81%D1%82%D1%8C-3-%D0%BC%D0%BE%D0%B8-%D0%BD%D0%BE%D1%81%D0%B8%D0%BC%D1%8B%D0%B5-%D1%83%D1%81%D1%82%D1%80%D0%BE%D0%B9%D1%81%D1%82%D0%B2%D0%B0-%D0%BB%D0%B3%D0%B0%D0%BB%D0%B8-%D0%BF%D0%BE-%D1%83%D0%BC%D0%BE%D0%BB%D1%87%D0%B0%D0%BD%D0%B8%D1%8E/</link><pubDate>Mon, 18 May 2026 00:00:00 +0000</pubDate><guid>https://dzarlax.dev/ru/articles/health-dashboard-%D1%87%D0%B0%D1%81%D1%82%D1%8C-3-%D0%BC%D0%BE%D0%B8-%D0%BD%D0%BE%D1%81%D0%B8%D0%BC%D1%8B%D0%B5-%D1%83%D1%81%D1%82%D1%80%D0%BE%D0%B9%D1%81%D1%82%D0%B2%D0%B0-%D0%BB%D0%B3%D0%B0%D0%BB%D0%B8-%D0%BF%D0%BE-%D1%83%D0%BC%D0%BE%D0%BB%D1%87%D0%B0%D0%BD%D0%B8%D1%8E/</guid><description>&lt;p&gt;После части 2 ingestion-слой выглядит чистым. Сервер принимает payload-ы, нативный iOS-клиент работает рядом с Health Auto Export, схема знает про посегментный сон, дашборд показывает пять фаз сна. Кажется, всё готово. Нет.&lt;/p&gt;
&lt;p&gt;Следующий класс проблем стал виден только после того, как данные стали технически корректными. В любую ночь у меня есть &lt;strong&gt;три устройства&lt;/strong&gt;, которые могут что-то сказать о моём сне: Apple Watch на запястье, RingConn&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; на пальце и iPhone рядом с кроватью, который использует собственную оценку Apple Sleep Schedule. Каждое из них знает что-то, чего не знают остальные. И ни одно из них не согласно с другими насчёт того, что именно оно измерило.&lt;/p&gt;</description></item><item><title>Health Dashboard, часть 4: когда готовность перестала быть одним числом</title><link>https://dzarlax.dev/ru/articles/health-dashboard-%D1%87%D0%B0%D1%81%D1%82%D1%8C-4-%D0%BA%D0%BE%D0%B3%D0%B4%D0%B0-%D0%B3%D0%BE%D1%82%D0%BE%D0%B2%D0%BD%D0%BE%D1%81%D1%82%D1%8C-%D0%BF%D0%B5%D1%80%D0%B5%D1%81%D1%82%D0%B0%D0%BB%D0%B0-%D0%B1%D1%8B%D1%82%D1%8C-%D0%BE%D0%B4%D0%BD%D0%B8%D0%BC-%D1%87%D0%B8%D1%81%D0%BB%D0%BE%D0%BC/</link><pubDate>Mon, 18 May 2026 00:00:00 +0000</pubDate><guid>https://dzarlax.dev/ru/articles/health-dashboard-%D1%87%D0%B0%D1%81%D1%82%D1%8C-4-%D0%BA%D0%BE%D0%B3%D0%B4%D0%B0-%D0%B3%D0%BE%D1%82%D0%BE%D0%B2%D0%BD%D0%BE%D1%81%D1%82%D1%8C-%D0%BF%D0%B5%D1%80%D0%B5%D1%81%D1%82%D0%B0%D0%BB%D0%B0-%D0%B1%D1%8B%D1%82%D1%8C-%D0%BE%D0%B4%D0%BD%D0%B8%D0%BC-%D1%87%D0%B8%D1%81%D0%BB%D0%BE%D0%BC/</guid><description>&lt;p&gt;В части 1 я описал исходный readiness score:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;readiness = HRV_score * 0.40 + RHR_score * 0.30 + Sleep_score * 0.30
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Это было полезное число. Каждое утро оно показывало, выглядит ли что-то в данных прошлой ночи необычно относительно моего личного baseline. А ещё оказалось, что оно измеряет не то.&lt;/p&gt;
&lt;p&gt;Эта часть — об аудите, который это вскрыл, о редизайне, который из него вырос, и о моменте, когда Фаза 1 закрылась без единой модели, которая превзошла бы свой наивный baseline по заранее заданному критерию.&lt;/p&gt;</description></item><item><title>Health Dashboard, часть 5: проблема EnergyBank</title><link>https://dzarlax.dev/ru/articles/health-dashboard-%D1%87%D0%B0%D1%81%D1%82%D1%8C-5-%D0%BF%D1%80%D0%BE%D0%B1%D0%BB%D0%B5%D0%BC%D0%B0-energybank/</link><pubDate>Mon, 18 May 2026 00:00:00 +0000</pubDate><guid>https://dzarlax.dev/ru/articles/health-dashboard-%D1%87%D0%B0%D1%81%D1%82%D1%8C-5-%D0%BF%D1%80%D0%BE%D0%B1%D0%BB%D0%B5%D0%BC%D0%B0-energybank/</guid><description>&lt;p&gt;В части 4 аудит обнулил readiness-формулу и выявил параллельный факт: EnergyBank v1 имел противоположный знак корреляции с HRV&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; следующего дня (r=−0.149) и RHR&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt; следующего дня (r=+0.212) за 387 парных дней.&lt;/p&gt;
&lt;p&gt;Противоположный знак корреляции — это сильное утверждение. Это означает, что сама концепция жива, но target был задан неверно: то, что измерял v1, вероятно, было &lt;em&gt;productive strain&lt;/em&gt;, а не &lt;em&gt;recovery deficit&lt;/em&gt;. Эти два показателя коррелируют во многие дни и расходятся именно там, где это важнее всего: в тихий, но тревожный день, во время болезни или когда часы сняты с запястья.&lt;/p&gt;</description></item><item><title>Health Dashboard, часть 6: измерять стресс без самообмана</title><link>https://dzarlax.dev/ru/articles/health-dashboard-%D1%87%D0%B0%D1%81%D1%82%D1%8C-6-%D0%B8%D0%B7%D0%BC%D0%B5%D1%80%D1%8F%D1%82%D1%8C-%D1%81%D1%82%D1%80%D0%B5%D1%81%D1%81-%D0%B1%D0%B5%D0%B7-%D1%81%D0%B0%D0%BC%D0%BE%D0%BE%D0%B1%D0%BC%D0%B0%D0%BD%D0%B0/</link><pubDate>Mon, 18 May 2026 00:00:00 +0000</pubDate><guid>https://dzarlax.dev/ru/articles/health-dashboard-%D1%87%D0%B0%D1%81%D1%82%D1%8C-6-%D0%B8%D0%B7%D0%BC%D0%B5%D1%80%D1%8F%D1%82%D1%8C-%D1%81%D1%82%D1%80%D0%B5%D1%81%D1%81-%D0%B1%D0%B5%D0%B7-%D1%81%D0%B0%D0%BC%D0%BE%D0%BE%D0%B1%D0%BC%D0%B0%D0%BD%D0%B0/</guid><description>&lt;p&gt;В части 5 редизайн EnergyBank оставил placeholder: &lt;code&gt;drain = α · active_kcal + β · sustained_hr_load&lt;/code&gt;, где &lt;code&gt;β = 0&lt;/code&gt; до тех пор, пока per-user validation rubric не вернёт &lt;code&gt;validated&lt;/code&gt;. Этот член уравнения — drain от autonomic load — относится к v2.2. И именно с ним я хотел быть особенно осторожным, потому что «стресс» — самая переобещанная метрика в consumer health.&lt;/p&gt;
&lt;p&gt;Эта часть — о том, что стресс вообще означает физиологически, что мои данные могут и не могут о нём сказать, почему очевидная формула была неправильной и зачем нужна validation rubric.&lt;/p&gt;</description></item><item><title>Health Dashboard, часть 7: приложение, которое перестало считать</title><link>https://dzarlax.dev/ru/articles/health-dashboard-%D1%87%D0%B0%D1%81%D1%82%D1%8C-7-%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BA%D0%BE%D1%82%D0%BE%D1%80%D0%BE%D0%B5-%D0%BF%D0%B5%D1%80%D0%B5%D1%81%D1%82%D0%B0%D0%BB%D0%BE-%D1%81%D1%87%D0%B8%D1%82%D0%B0%D1%82%D1%8C/</link><pubDate>Mon, 18 May 2026 00:00:00 +0000</pubDate><guid>https://dzarlax.dev/ru/articles/health-dashboard-%D1%87%D0%B0%D1%81%D1%82%D1%8C-7-%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BA%D0%BE%D1%82%D0%BE%D1%80%D0%BE%D0%B5-%D0%BF%D0%B5%D1%80%D0%B5%D1%81%D1%82%D0%B0%D0%BB%D0%BE-%D1%81%D1%87%D0%B8%D1%82%D0%B0%D1%82%D1%8C/</guid><description>&lt;p&gt;Первые шесть частей этой серии были о том, как сервер учится иметь собственные мнения. Ingestion gates, идентичность источника, eligibility для sub-scores, границы версий формул, validation rubrics — каждый слой заслужил право выдавать число. Когда эта работа была сделана, на другой стороне провода появился новый вопрос: что iOS-клиенту вообще разрешено делать с этими числами?&lt;/p&gt;
&lt;p&gt;Ответ оказался уже, чем я ожидал в начале. Самая интересная часть создания мобильного приложения была не в том, что в него добавлялось. А в том, что из него снова и снова &lt;em&gt;удалялось&lt;/em&gt;, пока сервер учился делать каждую вещь лучше.&lt;/p&gt;</description></item><item><title>Health Dashboard, часть 8: сначала спросить, потом говорить</title><link>https://dzarlax.dev/ru/articles/health-dashboard-%D1%87%D0%B0%D1%81%D1%82%D1%8C-8-%D1%81%D0%BD%D0%B0%D1%87%D0%B0%D0%BB%D0%B0-%D1%81%D0%BF%D1%80%D0%BE%D1%81%D0%B8%D1%82%D1%8C-%D0%BF%D0%BE%D1%82%D0%BE%D0%BC-%D0%B3%D0%BE%D0%B2%D0%BE%D1%80%D0%B8%D1%82%D1%8C/</link><pubDate>Mon, 18 May 2026 00:00:00 +0000</pubDate><guid>https://dzarlax.dev/ru/articles/health-dashboard-%D1%87%D0%B0%D1%81%D1%82%D1%8C-8-%D1%81%D0%BD%D0%B0%D1%87%D0%B0%D0%BB%D0%B0-%D1%81%D0%BF%D1%80%D0%BE%D1%81%D0%B8%D1%82%D1%8C-%D0%BF%D0%BE%D1%82%D0%BE%D0%BC-%D0%B3%D0%BE%D0%B2%D0%BE%D1%80%D0%B8%D1%82%D1%8C/</guid><description>&lt;p&gt;В части 6 было сформулировано правило: subjective input не может подтвердить формулу стресса. Это правило остается в силе. Формула, которая автоматически настраивается на user self-report, становится замкнутым циклом без внешней опоры. Пользователь рационализирует post-hoc, формула обновляется в сторону рационализации, и следующий раунд самоотчёта искажается предыдущим результатом формулы. Лекарство от этого — держать rubric внешней: HRV на следующее утро, сдвиг RHR, архитектура сна. Числа, которые пользователь не записывает сознательно.&lt;/p&gt;
&lt;p&gt;Почему же тогда, спустя несколько недель, я выпустил утренний one-tap check-in, который спрашивает пользователя, как он себя чувствует?&lt;/p&gt;</description></item><item><title>Дашборд здоровья, часть 2: Выход за рамки Health Auto Export</title><link>https://dzarlax.dev/ru/articles/%D0%B4%D0%B0%D1%88%D0%B1%D0%BE%D1%80%D0%B4-%D0%B7%D0%B4%D0%BE%D1%80%D0%BE%D0%B2%D1%8C%D1%8F-%D1%87%D0%B0%D1%81%D1%82%D1%8C-2-%D0%B2%D1%8B%D1%85%D0%BE%D0%B4-%D0%B7%D0%B0-%D1%80%D0%B0%D0%BC%D0%BA%D0%B8-health-auto-export/</link><pubDate>Mon, 18 May 2026 00:00:00 +0000</pubDate><guid>https://dzarlax.dev/ru/articles/%D0%B4%D0%B0%D1%88%D0%B1%D0%BE%D1%80%D0%B4-%D0%B7%D0%B4%D0%BE%D1%80%D0%BE%D0%B2%D1%8C%D1%8F-%D1%87%D0%B0%D1%81%D1%82%D1%8C-2-%D0%B2%D1%8B%D1%85%D0%BE%D0%B4-%D0%B7%D0%B0-%D1%80%D0%B0%D0%BC%D0%BA%D0%B8-health-auto-export/</guid><description>&lt;p&gt;В части 1 сервер научился принимать наблюдения, не теряя их, и пересобирать каждую производную таблицу из сырых данных. Этого хватило, чтобы сделать дашборд полезным. Но не хватило, чтобы сделать данные честными.&lt;/p&gt;
&lt;p&gt;Эта часть — о моменте, когда стороннего экспортёра перестало хватать как самостоятельного ingestion path, и о двух регрессиях, которые появились после того, как я добавил рядом с ним собственный iOS-клиент. Health Auto Export всё ещё отправляет данные на сервер. Endpoint &lt;code&gt;/health&lt;/code&gt; принимает оба источника, а кодовый путь, который парсит HAE payload-ы, по-прежнему поддерживается. «Выход за пределы» в заголовке — про ограничения HAE, а не про то, что я его выкинул.&lt;/p&gt;</description></item><item><title>Панель здоровья, часть 1: оценка, которой я могу доверять</title><link>https://dzarlax.dev/ru/articles/%D0%BF%D0%B0%D0%BD%D0%B5%D0%BB%D1%8C-%D0%B7%D0%B4%D0%BE%D1%80%D0%BE%D0%B2%D1%8C%D1%8F-%D1%87%D0%B0%D1%81%D1%82%D1%8C-1-%D0%BE%D1%86%D0%B5%D0%BD%D0%BA%D0%B0-%D0%BA%D0%BE%D1%82%D0%BE%D1%80%D0%BE%D0%B9-%D1%8F-%D0%BC%D0%BE%D0%B3%D1%83-%D0%B4%D0%BE%D0%B2%D0%B5%D1%80%D1%8F%D1%82%D1%8C/</link><pubDate>Mon, 18 May 2026 00:00:00 +0000</pubDate><guid>https://dzarlax.dev/ru/articles/%D0%BF%D0%B0%D0%BD%D0%B5%D0%BB%D1%8C-%D0%B7%D0%B4%D0%BE%D1%80%D0%BE%D0%B2%D1%8C%D1%8F-%D1%87%D0%B0%D1%81%D1%82%D1%8C-1-%D0%BE%D1%86%D0%B5%D0%BD%D0%BA%D0%B0-%D0%BA%D0%BE%D1%82%D0%BE%D1%80%D0%BE%D0%B9-%D1%8F-%D0%BC%D0%BE%D0%B3%D1%83-%D0%B4%D0%BE%D0%B2%D0%B5%D1%80%D1%8F%D1%82%D1%8C/</guid><description>&lt;p&gt;Это первая часть серии о создании моего self-hosted Health Dashboard. Первая версия не была методологическим проектом. Это была труба: взять данные из Apple Health, отправить их POST-запросом на мой сервер и утром показать оценку.&lt;/p&gt;
&lt;p&gt;Звучит чисто — пока в Postgres не приземляется первая плохая ночь. Оценка здоровья надёжна ровно настолько, насколько надёжен путь приёма данных под ней. Ранняя версия системы вбивала мне этот урок через ошибки.&lt;/p&gt;
&lt;p&gt;Один из первых режимов сбоя выглядел так:&lt;/p&gt;</description></item><item><title>Как я заменил менеджер закладок на 1,3 ГБ инструментом на 17 МБ</title><link>https://dzarlax.dev/ru/articles/%D0%BA%D0%B0%D0%BA-%D1%8F-%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B8%D0%BB-%D0%BC%D0%B5%D0%BD%D0%B5%D0%B4%D0%B6%D0%B5%D1%80-%D0%B7%D0%B0%D0%BA%D0%BB%D0%B0%D0%B4%D0%BE%D0%BA-%D0%BD%D0%B0-13-%D0%B3%D0%B1-%D0%B8%D0%BD%D1%81%D1%82%D1%80%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%BC-%D0%BD%D0%B0-17-%D0%BC%D0%B1/</link><pubDate>Wed, 13 May 2026 00:00:00 +0000</pubDate><guid>https://dzarlax.dev/ru/articles/%D0%BA%D0%B0%D0%BA-%D1%8F-%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B8%D0%BB-%D0%BC%D0%B5%D0%BD%D0%B5%D0%B4%D0%B6%D0%B5%D1%80-%D0%B7%D0%B0%D0%BA%D0%BB%D0%B0%D0%B4%D0%BE%D0%BA-%D0%BD%D0%B0-13-%D0%B3%D0%B1-%D0%B8%D0%BD%D1%81%D1%82%D1%80%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%BC-%D0%BD%D0%B0-17-%D0%BC%D0%B1/</guid><description>&lt;p&gt;Я довольно долго закрывал на это глаза: каждый раз, когда я смотрел &lt;code&gt;docker stats&lt;/code&gt; на своём Hetzner VPS, Karakeep с большим отрывом оказывался самым тяжёлым контейнером. Машина с 7,6 ГБ RAM, 25 сервисов — и одно Node-приложение, которое держит &lt;strong&gt;1,32 ГБ&lt;/strong&gt; резидентной памяти ради того, что в моём случае было просто навороченным списком ссылок со скриншотами.&lt;/p&gt;
&lt;p&gt;Доступной памяти оставалось &lt;strong&gt;1,4 ГБ&lt;/strong&gt;, swap упирался в 2,0 / 2,0 ГБ, а Postgres с лимитом 768 МБ доходил до 61% использования. Ничего не горело, но запас перестал ощущаться запасом.&lt;/p&gt;</description></item></channel></rss>