<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>KHTDR – Apps</title><description/><link>https://khtdr.com/categories/apps.html</link><lastBuildDate>Sun, 27 Sep 2026 00:00:00 -0600</lastBuildDate><language>en-us</language><managingEditor>mazzarelli@gmail.com (Joey Mazzarelli)</managingEditor><webMaster>mazzarelli@gmail.com (Joey Mazzarelli)</webMaster><atom:link href="https://khtdr.com/categories/apps/index.xml" rel="self" type="application/rss+xml"/><item><title>Zazen</title><description> Zazen is a meditation timer for Android, and that is all it is. You pick a length, it gives you a few seconds to settle in, a bell starts the sit, a soft bed of noise plays underneath, and a bell ends it. There are no accounts, stats, streaks, or history, and it never nags you to sit.
Get the app Android APK: Download Zazen 1.0.0 (~41 MB, Android 7.0 or newer, 64-bit phones) Google Play: not published. This is a direct download. iOS: not planned Point your phone's camera at this to download the APK (~41&nbsp;MB). If you want to confirm the file you downloaded is the one I published, its SHA-256 is:</description><link>https://khtdr.com/zazen/</link><guid>https://khtdr.com/zazen/</guid><pubDate>Sun, 27 Sep 2026 00:00:00 -0600</pubDate><author>mazzarelli@gmail.com (Joey Mazzarelli)</author><category>Apps</category><content:encoded>
&lt;![CDATA[
&lt;p&gt;
&lt;strong&gt;Zazen&lt;/strong&gt; is a meditation timer for Android, and that is all it is. You pick a length, it gives
you a few seconds to settle in, a bell starts the sit, a soft bed of noise plays underneath, and
a bell ends it. There are no accounts, stats, streaks, or history, and it never nags you to sit.&lt;/p&gt;
&lt;div id="outline-container-headline-1" class="outline-2"&gt;
&lt;h2 id="headline-1"&gt;
Get the app
&lt;/h2&gt;
&lt;div id="outline-text-headline-1" class="outline-text-2"&gt;
&lt;ul&gt;
&lt;li&gt;Android APK: &lt;a href="https://khtdr.com/zazen/zazen-1.0.0.apk"&gt;Download Zazen 1.0.0&lt;/a&gt; &lt;em&gt;(~41 MB, Android 7.0 or newer, 64-bit phones)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Google Play: &lt;em&gt;not published. This is a direct download.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;iOS: &lt;em&gt;not planned&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure style="margin:1.5rem 0;text-align:center"&gt;
&lt;a href="https://khtdr.com/zazen/zazen-1.0.0.apk"&gt;
&lt;img src="https://khtdr.com/zazen/download-qr.svg" alt="QR code linking to the Zazen APK download"
width="200" height="200"
style="width:200px;height:200px;background:#fff;padding:10px;border-radius:8px;display:inline-block" /&gt;
&lt;/a&gt;
&lt;figcaption style="font-size:0.9em;opacity:0.75;margin-top:0.5rem"&gt;
Point your phone's camera at this to download the APK (~41&amp;nbsp;MB).
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;
If you want to confirm the file you downloaded is the one I published, its SHA-256 is:&lt;/p&gt;
&lt;pre class="example"&gt;
7dab571f7849620cac3079797371bc3d60fd4ad7416774b9b054f8b854fc499d
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-headline-2" class="outline-2"&gt;
&lt;h2 id="headline-2"&gt;
Install
&lt;/h2&gt;
&lt;div id="outline-text-headline-2" class="outline-text-2"&gt;
&lt;p&gt;
Android only installs apps from the Play Store until you give permission, and you give it one
app at a time.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open the download link above on your phone.&lt;/li&gt;
&lt;li&gt;When it finishes, tap the downloaded file. Android will say your browser (or file manager)
isn&amp;#39;t allowed to install unknown apps. Tap &lt;strong&gt;Settings&lt;/strong&gt;, turn on &lt;strong&gt;Allow from this source&lt;/strong&gt;, then
go back.&lt;/li&gt;
&lt;li&gt;Tap &lt;strong&gt;Install&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Play Protect may warn you that it doesn&amp;#39;t recognize the developer. That&amp;#39;s expected, because
the app isn&amp;#39;t in the Play Store. Tap &lt;strong&gt;More details&lt;/strong&gt;, then &lt;strong&gt;Install anyway&lt;/strong&gt;, if you&amp;#39;re
comfortable with that.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can turn &lt;strong&gt;Allow from this source&lt;/strong&gt; back off afterward. It isn&amp;#39;t needed for updates.&lt;/p&gt;
&lt;div id="outline-container-headline-3" class="outline-3"&gt;
&lt;h3 id="headline-3"&gt;
Updates
&lt;/h3&gt;
&lt;div id="outline-text-headline-3" class="outline-text-3"&gt;
&lt;p&gt;
Most updates arrive on their own. The app checks for one when it opens and downloads it in the
background. The update takes effect the next time you open the app, never in the middle of a
sit. You only need to download a new APK when the version number on this page changes. You can
also check for an update yourself under &lt;strong&gt;settings → Updates&lt;/strong&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-headline-4" class="outline-2"&gt;
&lt;h2 id="headline-4"&gt;
How a sit goes
&lt;/h2&gt;
&lt;div id="outline-text-headline-4" class="outline-text-2"&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Pick a length.&lt;/strong&gt; 5, 10, 20, or 30 minutes, or your own length from 1 to 120.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Settle in.&lt;/strong&gt; The screen counts down a short pause (10 seconds unless you change it). Toward
the end, a bowl sings as it&amp;#39;s rubbed around its rim, so you already know the bell&amp;#39;s pitch
when it&amp;#39;s struck.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The start bell.&lt;/strong&gt; Once it has rung out, the bed of noise fades in.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sit.&lt;/strong&gt; If you like, a soft bell marks the halfway point, or every 5 or 10 minutes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The end bell.&lt;/strong&gt; The noise either settles down under the bell or fades out before it, so the
bell rings alone.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can cancel at any point, and the sounds fade out rather than cut off. The sit keeps time by
the clock, not by counting seconds, so locking the phone or switching apps doesn&amp;#39;t throw it
off. The whole sit is scheduled the moment you tap, so you still hear the bells with the screen
locked.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-headline-5" class="outline-2"&gt;
&lt;h2 id="headline-5"&gt;
The sounds
&lt;/h2&gt;
&lt;div id="outline-text-headline-5" class="outline-text-2"&gt;
&lt;p&gt;
I really built this to have a clean place to play with sound, and there are no recordings in
it. Every sound is synthesized on the phone as it plays, using the Web Audio API
(through &lt;a href="https://docs.swmansion.com/react-native-audio-api/"&gt;react-native-audio-api&lt;/a&gt;).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The bells&lt;/strong&gt; are built from a handful of sine waves, one for each ringing tone of a real bell,
each fading at its own rate.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The rim&lt;/strong&gt; is the same tones, plus a band of noise for the friction of the mallet going around
the bowl.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The bed&lt;/strong&gt; comes in three characters:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;drift&lt;/em&gt;: pink, green, and brown noise slowly moving around each other and across the
stereo field, so it is never quite still. Underneath is an optional binaural beat, which you
only hear with headphones.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;pink&lt;/em&gt;: plain pink noise, like steady rain.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;brown&lt;/em&gt;: plain brown noise, darker, closer to surf.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nothing ever starts or stops at full volume. Every sound ramps in and out, because a click is
the last thing you want to hear ten minutes into a sit.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-headline-6" class="outline-2"&gt;
&lt;h2 id="headline-6"&gt;
Settings
&lt;/h2&gt;
&lt;div id="outline-text-headline-6" class="outline-text-2"&gt;
&lt;p&gt;
A small settings dialog holds everything you can change:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the bells on or off, their volume, and the interval bells&lt;/li&gt;
&lt;li&gt;the background noise on or off, its character, its volume, and the binaural beat&lt;/li&gt;
&lt;li&gt;how the noise ends: settling under the end bell, or fading out before it&lt;/li&gt;
&lt;li&gt;the settling-in pause: 5, 10, or 30 seconds&lt;/li&gt;
&lt;li&gt;your own sit length&lt;/li&gt;
&lt;li&gt;whether the app closes itself once the last sound fades&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-headline-7" class="outline-2"&gt;
&lt;h2 id="headline-7"&gt;
Privacy
&lt;/h2&gt;
&lt;div id="outline-text-headline-7" class="outline-text-2"&gt;
&lt;p&gt;
Zazen doesn&amp;#39;t know who you are and doesn&amp;#39;t keep track of your sits. The only thing it saves is
your settings, in a small file on your phone. There are no ads, no analytics, no crash
reporting, and no notifications. The only thing it ever sends over the internet is the check
for app updates.&lt;/p&gt;
&lt;p&gt;
The app is free. It has no paid features, and I have no plans to add any.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
]]&gt;</content:encoded></item><item><title>Mood Ring</title><description> Mood Ring is a small Android app for noticing how you've been feeling. Now and then it asks a quick question, it has a short check-in at the end of the day, and it offers an occasional questionnaire. Then it shows you how things change over time. I made it for a small circle of friends and family, so it is not in the Play Store.
Get the app Android APK: Download Mood Ring 1.1.0 (~35 MB, Android 7.0 or newer, 64-bit phones) Google Play: not published. This is a direct download. iOS: not planned Point your phone's camera at this to download the APK (~35&nbsp;MB). If you want to confirm the file you downloaded is the one I published, its SHA-256 is:</description><link>https://khtdr.com/mood-ring/</link><guid>https://khtdr.com/mood-ring/</guid><pubDate>Fri, 25 Sep 2026 00:00:00 -0600</pubDate><author>mazzarelli@gmail.com (Joey Mazzarelli)</author><category>Apps</category><content:encoded>
&lt;![CDATA[
&lt;p&gt;
&lt;strong&gt;Mood Ring&lt;/strong&gt; is a small Android app for noticing how you&amp;#39;ve been feeling. Now and then it asks
a quick question, it has a short check-in at the end of the day, and it offers an occasional
questionnaire. Then it shows you how things change over time. I made it for a small circle of
friends and family, so it is not in the Play Store.&lt;/p&gt;
&lt;div id="outline-container-headline-1" class="outline-2"&gt;
&lt;h2 id="headline-1"&gt;
Get the app
&lt;/h2&gt;
&lt;div id="outline-text-headline-1" class="outline-text-2"&gt;
&lt;ul&gt;
&lt;li&gt;Android APK: &lt;a href="https://khtdr.com/mood-ring/mood-ring-1.1.0.apk"&gt;Download Mood Ring 1.1.0&lt;/a&gt; &lt;em&gt;(~35 MB, Android 7.0 or newer, 64-bit phones)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Google Play: &lt;em&gt;not published. This is a direct download.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;iOS: &lt;em&gt;not planned&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure style="margin:1.5rem 0;text-align:center"&gt;
&lt;a href="https://khtdr.com/mood-ring/mood-ring-1.1.0.apk"&gt;
&lt;img src="https://khtdr.com/mood-ring/download-qr.svg" alt="QR code linking to the Mood Ring APK download"
width="200" height="200"
style="width:200px;height:200px;background:#fff;padding:10px;border-radius:8px;display:inline-block" /&gt;
&lt;/a&gt;
&lt;figcaption style="font-size:0.9em;opacity:0.75;margin-top:0.5rem"&gt;
Point your phone's camera at this to download the APK (~35&amp;nbsp;MB).
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;
If you want to confirm the file you downloaded is the one I published, its SHA-256 is:&lt;/p&gt;
&lt;pre class="example"&gt;
657e8c7e6182276d92c8102633e193578cd27967364cb8628ad919f55b877021
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-headline-2" class="outline-2"&gt;
&lt;h2 id="headline-2"&gt;
Install
&lt;/h2&gt;
&lt;div id="outline-text-headline-2" class="outline-text-2"&gt;
&lt;div id="outline-container-headline-3" class="outline-3"&gt;
&lt;h3 id="headline-3"&gt;
1. Let your browser install apps
&lt;/h3&gt;
&lt;div id="outline-text-headline-3" class="outline-text-3"&gt;
&lt;p&gt;
Android only installs apps from the Play Store until you give permission, and you give it one
app at a time.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open the download link above on your phone.&lt;/li&gt;
&lt;li&gt;When it finishes, tap the downloaded file. Android will say your browser (or file manager)
isn&amp;#39;t allowed to install unknown apps. Tap &lt;strong&gt;Settings&lt;/strong&gt;, turn on &lt;strong&gt;Allow from this source&lt;/strong&gt;, then
go back.&lt;/li&gt;
&lt;li&gt;Tap &lt;strong&gt;Install&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Play Protect may warn you that it doesn&amp;#39;t recognize the developer. That&amp;#39;s expected, because
the app isn&amp;#39;t in the Play Store. Tap &lt;strong&gt;More details&lt;/strong&gt;, then &lt;strong&gt;Install anyway&lt;/strong&gt;, if you&amp;#39;re
comfortable with that.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can turn &lt;strong&gt;Allow from this source&lt;/strong&gt; back off afterward. It isn&amp;#39;t needed for updates.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-headline-4" class="outline-3"&gt;
&lt;h3 id="headline-4"&gt;
2. Let the reminders through
&lt;/h3&gt;
&lt;div id="outline-text-headline-4" class="outline-text-3"&gt;
&lt;p&gt;
The first time you open Mood Ring, it asks to send notifications. Say yes, or it can&amp;#39;t remind
you to check in.&lt;/p&gt;
&lt;p&gt;
Many phones also shut down background apps to save battery, which can make reminders show up
late or not at all. If your reminders don&amp;#39;t arrive:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open Android &lt;strong&gt;Settings → Apps → Mood Ring → Battery&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;Unrestricted&lt;/strong&gt; (some phones call it &lt;strong&gt;Don&amp;#39;t optimize&lt;/strong&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Samsung, Xiaomi, OnePlus, Huawei, and some other brands add their own extra battery settings.
&lt;a href="https://dontkillmyapp.com"&gt;dontkillmyapp.com&lt;/a&gt; has step-by-step instructions for each brand.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-headline-5" class="outline-3"&gt;
&lt;h3 id="headline-5"&gt;
Updates
&lt;/h3&gt;
&lt;div id="outline-text-headline-5" class="outline-text-3"&gt;
&lt;p&gt;
Most updates arrive on their own. The app checks for one when it opens and asks before it
restarts to apply it. You only need to download a new APK when the version number on this page
changes. You can see which version you have in the app under &lt;strong&gt;Settings → About Mood Ring&lt;/strong&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-headline-6" class="outline-3"&gt;
&lt;h3 id="headline-6"&gt;
Uninstalling
&lt;/h3&gt;
&lt;div id="outline-text-headline-6" class="outline-text-3"&gt;
&lt;p&gt;
Uninstalling Mood Ring deletes everything you&amp;#39;ve entered in it, unless Android backup is on (see
below). If you want to keep your history, use &lt;strong&gt;Export JSON&lt;/strong&gt; or &lt;strong&gt;Export CSV&lt;/strong&gt; under &lt;strong&gt;Settings → Your data&lt;/strong&gt; first and save the file
somewhere safe.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-headline-7" class="outline-2"&gt;
&lt;h2 id="headline-7"&gt;
What it does
&lt;/h2&gt;
&lt;div id="outline-text-headline-7" class="outline-text-2"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Quick nudges.&lt;/strong&gt; A few times a day, at random times within hours you choose, it asks &amp;#34;how are
you feeling right now?&amp;#34; Answering is one tap on a five-point scale from &lt;em&gt;Awful&lt;/em&gt; to &lt;em&gt;Great&lt;/em&gt;,
plus an optional energy rating.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;An end-of-day check-in.&lt;/strong&gt; A mood for the day, an optional note, and any questions you&amp;#39;ve added
yourself. For example, &amp;#34;Did you exercise?&amp;#34; (yes/no), &amp;#34;How well did you sleep?&amp;#34; (a 1–5 rating), or
&amp;#34;How many coffees?&amp;#34; (a count).&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Occasional questionnaires.&lt;/strong&gt; Short, widely used screening questionnaires, each on a schedule
you pick, such as every two weeks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GAD-7 (anxiety)&lt;/li&gt;
&lt;li&gt;PHQ-9 (depression)&lt;/li&gt;
&lt;li&gt;K10 (psychological distress)&lt;/li&gt;
&lt;li&gt;PSS-10 (stress)&lt;/li&gt;
&lt;li&gt;WHO-5 (wellbeing)&lt;/li&gt;
&lt;li&gt;UCLA 3-item (loneliness)&lt;/li&gt;
&lt;li&gt;Satisfaction With Life Scale&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;History.&lt;/strong&gt; A calendar colored by mood, and each day&amp;#39;s entries in detail.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The reminders are deliberately vague, like &amp;#34;How are you feeling right now?&amp;#34; or &amp;#34;How was today?&amp;#34; They never show a mood, a
score, or the name of a questionnaire, because notifications can show up on your lock screen.&lt;/p&gt;
&lt;div id="outline-container-headline-8" class="outline-3"&gt;
&lt;h3 id="headline-8"&gt;
It is not a diagnosis
&lt;/h3&gt;
&lt;div id="outline-text-headline-8" class="outline-text-3"&gt;
&lt;p&gt;
Mood Ring is not a diagnostic tool, and it doesn&amp;#39;t replace professional care. The questionnaires
are screening tools. If you&amp;#39;re worried about how you&amp;#39;ve been feeling, a doctor or other health
professional can help. The app has an &lt;em&gt;If you need help now&lt;/em&gt; screen with crisis lines. It works
offline. In the US, you can call or text &lt;strong&gt;988&lt;/strong&gt; at any time.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-headline-9" class="outline-2"&gt;
&lt;h2 id="headline-9"&gt;
Privacy
&lt;/h2&gt;
&lt;div id="outline-text-headline-9" class="outline-text-2"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;It stays on your phone.&lt;/strong&gt; Everything you enter is saved in a database on your phone. There is
no account to create and no server to sync to.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nobody else sees it.&lt;/strong&gt; There are no ads, no analytics, no crash reporting, and no third
parties. The only thing the app ever sends over the internet is the check for app updates, and
that check sends none of your data.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Your own Google backup.&lt;/strong&gt; Android backs up app data to your own Google account, so your
history can come back when you move to a new phone. If you&amp;#39;d rather it didn&amp;#39;t, turn it off in
Android &lt;strong&gt;Settings → Google → Backup&lt;/strong&gt;. That setting applies to the whole phone.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;You can take it with you, or delete it.&lt;/strong&gt; &lt;strong&gt;Settings&lt;/strong&gt; can export everything to a JSON or CSV
file that you save wherever you want, or delete all of it from the phone.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The app is free. It has no paid features, and I have no plans to add any.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
]]&gt;</content:encoded></item><item><title>The Well Rounded Climber</title><description> The Well Rounded Climber (tWRC) is an Android climbing log that tracks habits instead of grades. A V4 at one gym is not a V4 at another, and it is not a V4 outside. The app measures two things that do transfer: how your difficulty is distributed, and how varied your style is.
Get the app Android APK — Download the APK (v1.1.0, ~35 MB) Google Play — not published; this is a direct download iOS — not yet built Point a phone at this to download the APK directly (~35&nbsp;MB). Install Android blocks installs from outside the Play Store until you allow it, per-app:</description><link>https://khtdr.com/twrc/</link><guid>https://khtdr.com/twrc/</guid><pubDate>Sun, 30 Aug 2026 00:00:00 -0600</pubDate><author>mazzarelli@gmail.com (Joey Mazzarelli)</author><category>Apps</category><content:encoded>
&lt;![CDATA[
&lt;p&gt;
&lt;strong&gt;The Well Rounded Climber&lt;/strong&gt; (tWRC) is an Android climbing log that tracks habits instead of
grades. A V4 at one gym is not a V4 at another, and it is not a V4 outside. The app measures
two things that do transfer: how your difficulty is &lt;strong&gt;distributed&lt;/strong&gt;, and how varied your
&lt;strong&gt;style&lt;/strong&gt; is.&lt;/p&gt;
&lt;div id="outline-container-headline-1" class="outline-2"&gt;
&lt;h2 id="headline-1"&gt;
Get the app
&lt;/h2&gt;
&lt;div id="outline-text-headline-1" class="outline-text-2"&gt;
&lt;ul&gt;
&lt;li&gt;Android APK — &lt;a href="https://khtdr.com/twrc/latest.apk"&gt;Download the APK&lt;/a&gt; &lt;em&gt;(v1.1.0, ~35 MB)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Google Play — &lt;em&gt;not published; this is a direct download&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;iOS — &lt;em&gt;not yet built&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure style="margin:1.5rem 0;text-align:center"&gt;
&lt;a href="https://khtdr.com/twrc/latest.apk"&gt;
&lt;img src="https://khtdr.com/twrc/download-qr.svg" alt="QR code linking to the tWRC APK download"
width="200" height="200"
style="width:200px;height:200px;background:#fff;padding:10px;border-radius:8px;display:inline-block" /&gt;
&lt;/a&gt;
&lt;figcaption style="font-size:0.9em;opacity:0.75;margin-top:0.5rem"&gt;
Point a phone at this to download the APK directly (~35&amp;nbsp;MB).
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;div id="outline-container-headline-2" class="outline-3"&gt;
&lt;h3 id="headline-2"&gt;
Install
&lt;/h3&gt;
&lt;div id="outline-text-headline-2" class="outline-text-3"&gt;
&lt;p&gt;
Android blocks installs from outside the Play Store until you allow it, per-app:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Download the &lt;code class="verbatim"&gt;.apk&lt;/code&gt; above on the phone (or copy it over).&lt;/li&gt;
&lt;li&gt;Tap it. Android will offer to let your browser or file manager install unknown apps —
grant that, then tap the file again.&lt;/li&gt;
&lt;li&gt;Play Protect may warn you it does not recognize the developer. It does not; I am not in
the Play Store. Install anyway if you are comfortable with that.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;After that, app updates arrive over the air on launch. You only need a new APK when the
native side changes.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-headline-3" class="outline-2"&gt;
&lt;h2 id="headline-3"&gt;
Why not grades?
&lt;/h2&gt;
&lt;div id="outline-text-headline-3" class="outline-text-2"&gt;
&lt;p&gt;
Grades are the main way climbers talk about difficulty, but they are a weak training signal.
They depend on the gym, the setter, and the style. Chasing them tends to push you toward the
climbs you are already good at, one grade below your limit, on the wall angle you like.&lt;/p&gt;
&lt;p&gt;
So tWRC never asks what a route was graded. It asks two questions instead.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-headline-4" class="outline-2"&gt;
&lt;h2 id="headline-4"&gt;
The Pyramid — are you distributing your effort?
&lt;/h2&gt;
&lt;div id="outline-text-headline-4" class="outline-text-2"&gt;
&lt;p&gt;
Every climb gets self-classified into one of three &lt;strong&gt;personal&lt;/strong&gt; buckets, defined against your
ability today rather than any gym&amp;#39;s scale:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Base&lt;/strong&gt; — easy mileage. Volume, movement, warm-up.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Core&lt;/strong&gt; — hard but doable. Your working level.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stretch&lt;/strong&gt; — at or past your limit. Projects.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A healthy season is pyramid-shaped: a lot of base, a solid core, a few stretch. The chart
shows you the shape you actually climbed.&lt;/p&gt;
&lt;p&gt;
There is &lt;strong&gt;no score, no percentage, and no verdict&lt;/strong&gt;. What you get is a named gap, where you
sat, and one small suggestion you can go check:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Last session: 8 base, 13 core, 1 stretch. Your last 6 weeks run core-heavy.&lt;/p&gt;
&lt;p&gt;
Next session: pick two slab problems.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
There is a subtlety here that took a rewrite to find. The bars are drawn from &lt;strong&gt;effort&lt;/strong&gt;
(attempts plus a completion bonus), but the judgement about which way your training &lt;strong&gt;leans&lt;/strong&gt;
is computed from plain &lt;strong&gt;counts&lt;/strong&gt; — one climb, one climb. If the lean were scored on effort
instead, a single twelve-attempt project would outweigh an eight-problem warm-up block, and
every session where you genuinely projected would read as &amp;#34;top-heavy.&amp;#34; Sandbagging would
score better than trying hard, for the exact climber this app is for. Now a project is one
climb, because it &lt;strong&gt;is&lt;/strong&gt; one climb.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-headline-5" class="outline-2"&gt;
&lt;h2 id="headline-5"&gt;
The Spiders — are you climbing everything?
&lt;/h2&gt;
&lt;div id="outline-text-headline-5" class="outline-text-2"&gt;
&lt;p&gt;
Three radar charts, tagged in the moment on any climb:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Hold Type&lt;/strong&gt; — crimp, sloper, pinch, jug, pocket, volume, crack&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wall Angle&lt;/strong&gt; — slab, vertical, overhang, roof, arete, stem&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Movement&lt;/strong&gt; — dyno, static, mantle, compression, lock-off&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Tags are not exclusive: one climb can be a crimpy overhanging lock-off, and it counts in all
three webs. Spokes are a raw tally — every tagged climb counts once, whether you onsighted it
or failed on it for fifteen attempts, because the question a web answers is &amp;#34;have you touched
this?&amp;#34; and a climb answers that once.&lt;/p&gt;
&lt;p&gt;
The tally only becomes useful with a denominator, so the webs report in sentences:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You logged 4 slab problems in 90 days, out of 210 climbs.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
&amp;#34;4 slab&amp;#34; reads as a preference. &amp;#34;4 out of 210&amp;#34; is a gap.&lt;/p&gt;
&lt;div id="outline-container-headline-6" class="outline-3"&gt;
&lt;h3 id="headline-6"&gt;
The taxonomy is yours
&lt;/h3&gt;
&lt;div id="outline-text-headline-6" class="outline-text-3"&gt;
&lt;p&gt;
Those eighteen dimensions are a starting point, not a rule. Your gym does not set cracks? A
crack spoke pinned at zero will read as a gap nobody can close, so turn it off. Add your own.
Turning one back on restores its whole history; nothing is deleted when it is hidden.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-headline-7" class="outline-2"&gt;
&lt;h2 id="headline-7"&gt;
Logging has to be fast or it doesn&amp;#39;t happen
&lt;/h2&gt;
&lt;div id="outline-text-headline-7" class="outline-text-2"&gt;
&lt;p&gt;
If logging is slow, you will not do it. The form is built to be quick:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Level picks the form.&lt;/strong&gt; Base asks nothing but &amp;#34;how many.&amp;#34; Core asks the result and offers
a one-tap &amp;#34;battled it.&amp;#34; Stretch — the only place a count actually matters — asks for
attempts on a keypad. One form serves three very different climbers, and it adapts &lt;strong&gt;within&lt;/strong&gt;
a single session, which a global &amp;#34;advanced mode&amp;#34; toggle never could.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tags carry over&lt;/strong&gt; from your last climb within a session, so a session on the same wall is
one tap per problem. They are not saved overnight — last night&amp;#39;s overhang should not attach
to tomorrow&amp;#39;s slab session.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;There is an end-of-session pass&lt;/strong&gt; that shows today&amp;#39;s untagged climbs with a few recallable
chips, for when you were too pumped to tag at the time.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No modes, no onboarding questionnaire.&lt;/strong&gt; Nothing to configure before you can log a climb.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-headline-8" class="outline-2"&gt;
&lt;h2 id="headline-8"&gt;
Make it yours
&lt;/h2&gt;
&lt;div id="outline-text-headline-8" class="outline-text-2"&gt;
&lt;p&gt;
Pick three colors — canvas, accent, and a chart seed — and the app derives its entire theme
from them. Every text color is checked against every background it lands on and corrected
until it clears WCAG AA contrast, including for bad picks. A bad color choice should not
leave you stuck in an unreadable settings screen you cannot see.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-headline-9" class="outline-2"&gt;
&lt;h2 id="headline-9"&gt;
No ads, no tracking, no paid features
&lt;/h2&gt;
&lt;div id="outline-text-headline-9" class="outline-text-2"&gt;
&lt;p&gt;
The app is free. There are no ads, no tracking, and no paid features, and there are no plans
to add any. Everything you log lives in a SQLite database on your phone — no account, no
server, no sync, nothing to sign up for, and nothing leaves the device.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
]]&gt;</content:encoded></item><item><title>pexro</title><description> pexro (Personal EXercise ROutine) is a personal mobile app that runs and tracks exercise programs described by uploaded JSON. No workout is hard-coded — the app is a generic interpreter over a schema. Describe a routine once, upload it, and pexro guides you through each session and tracks your progress over time.
Get the app Google Play — Download on Google Play (link coming soon) Apple App Store — Download on the App Store (link coming soon) Create your program with an LLM pexro doesn't ship a fixed routine — it runs a JSON program file you upload. The easiest way to make one is to let a language model write it for you.</description><link>https://khtdr.com/pexro/</link><guid>https://khtdr.com/pexro/</guid><pubDate>Mon, 13 Jul 2026 00:00:00 -0600</pubDate><author>mazzarelli@gmail.com (Joey Mazzarelli)</author><category>Apps</category><content:encoded>
&lt;![CDATA[
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;pexro&lt;/strong&gt; (Personal EXercise ROutine) is a personal mobile app that runs and tracks
exercise programs described by uploaded JSON. No workout is hard-coded — the app is a
generic interpreter over a schema. Describe a routine once, upload it, and pexro guides you
through each session and tracks your progress over time.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div id="outline-container-headline-1" class="outline-2"&gt;
&lt;h2 id="headline-1"&gt;
Get the app
&lt;/h2&gt;
&lt;div id="outline-text-headline-1" class="outline-text-2"&gt;
&lt;ul&gt;
&lt;li&gt;Google Play — &lt;a href="#"&gt;Download on Google Play&lt;/a&gt; &lt;em&gt;(link coming soon)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Apple App Store — &lt;a href="#"&gt;Download on the App Store&lt;/a&gt; &lt;em&gt;(link coming soon)&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-headline-2" class="outline-2"&gt;
&lt;h2 id="headline-2"&gt;
Create your program with an LLM
&lt;/h2&gt;
&lt;div id="outline-text-headline-2" class="outline-text-2"&gt;
&lt;p&gt;
pexro doesn&amp;#39;t ship a fixed routine — it runs a JSON &lt;strong&gt;program file&lt;/strong&gt; you upload. The easiest way
to make one is to let a language model write it for you.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open your LLM of choice (ChatGPT, Claude, Gemini, etc.).&lt;/li&gt;
&lt;li&gt;Give it the following prompt (use the &lt;strong&gt;Copy&lt;/strong&gt; button, then paste it into the chat):&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="copy-prompt"&gt;
&lt;button
class="copy-prompt-btn"
type="button"
aria-label="Copy prompt to clipboard"
onclick="
(function (b) {
var t = b
.closest('.copy-prompt')
.querySelector('.copy-prompt-text')
.innerText.trim();
navigator.clipboard.writeText(t).then(function () {
b.classList.add('copied');
var o = b.getAttribute('data-label');
b.firstChild.nodeValue = 'Copied! ';
setTimeout(function () {
b.firstChild.nodeValue = o;
b.classList.remove('copied');
}, 1600);
});
})(this)
"
data-label="Copy "
&gt;
Copy &lt;span class="copy-prompt-icon" aria-hidden="true"&gt;⧉&lt;/span&gt;
&lt;/button&gt;
&lt;blockquote class="copy-prompt-text"&gt;
I want you to build me a personal exercise program for a mobile app called pexro. First, read the authoring guide and JSON schema at https://khtdr.com/pexro/llm.txt and follow it exactly. Then ask me about my goals, experience level, available equipment, any injuries, and how many days per week I want to train — before writing anything. Finally, output a single valid JSON program file that conforms to the schema, inside a code block so I can copy it. I&amp;#39;ll import it into pexro either by pasting the JSON straight from this chat or by saving it as a .json file, so make sure the whole program is in one self-contained block.
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;Answer the model&amp;#39;s questions. It will hand back a JSON program.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Import it into pexro one of two ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Paste from clipboard&lt;/strong&gt; — copy the JSON out of the chat and paste it directly into pexro.
No file needed.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;From a file&lt;/strong&gt; — or save the output as a &lt;code class="verbatim"&gt;.json&lt;/code&gt; file on your device and upload that.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Either way, the app validates the program on import and shows a clear error if anything is
off — fix and re-import.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That&amp;#39;s it. Change your training later? Ask for new JSON and import it again — your logged
history is kept separate and carries over.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-headline-3" class="outline-2"&gt;
&lt;h2 id="headline-3"&gt;
For developers &amp;amp; LLMs
&lt;/h2&gt;
&lt;div id="outline-text-headline-3" class="outline-text-2"&gt;
&lt;p&gt;
The full authoring guide, a complete example, and the machine-readable schema live in plain
text:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Authoring guide (for LLMs): &lt;a href="https://khtdr.com/pexro/llm.txt"&gt;khtdr.com/pexro/llm.txt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;JSON Schema (draft 2020-12): &lt;a href="https://khtdr.com/pexro/schema.json"&gt;khtdr.com/pexro/schema.json&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
]]&gt;</content:encoded></item></channel></rss>