<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="https://lagerland-apps.github.io/" xml:lang="en">
  <title>Lagerland Apps — Journal</title>
  <subtitle>Sourced how-to guides (sleep, strength training, bills, pet health, chess, shogi, xiangqi, App Store Connect) and essays from a one-person, privacy-first Apple app studio.</subtitle>
  <link href="https://lagerland-apps.github.io/feed.xml" rel="self"/>
  <link href="https://lagerland-apps.github.io/journal/"/>
  <updated>2026-10-26T00:00:00+00:00</updated>
  <id>https://lagerland-apps.github.io/</id>
  <author>
    <name>Lagerland Apps</name>
    <email>lagerland.apps@proton.me</email>
    <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
  </author>
  <rights>&#169; 2026 Lagerland Apps</rights>
  <icon>https://lagerland-apps.github.io/assets/icons/lagerland-mark.png</icon>
  <logo>https://lagerland-apps.github.io/assets/icons/lagerland-mark.png</logo>

  <entry>
    <title>How long to rest between sets: what the studies found, lift by lift</title>
    <link href="https://lagerland-apps.github.io/journal/how-long-to-rest-between-sets/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/how-long-to-rest-between-sets/</id>
    <published>2026-10-21T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Most of a strength session is rest. A set of eight takes about half a minute; the gap before the next one takes two or three. So the rest timer decides how long you are in the gym more than the program does. The old rule was one minute for size and three for strength. The research has moved since then, including a new American College of Sports Medicine review this year. Here is what it says now, by lift and by goal.</summary>
    <content type="html">&lt;p&gt;The rest timer is the dullest setting in a training log, and it decides how long a session takes. Five exercises, three sets each, three minutes between sets: that is about 40 minutes of rest. Halve the rest and the session loses about 20 minutes. Whether you lose anything else depends on the lift.&lt;/p&gt;

&lt;h2 id=&quot;how-long-should-you-rest-between-sets&quot;&gt;How long should you rest between sets?&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Situation&lt;/th&gt;
      &lt;th&gt;Rest&lt;/th&gt;
      &lt;th&gt;Where the number comes from&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Very heavy compound sets, 1-5 reps&lt;/td&gt;
      &lt;td&gt;3-5 min&lt;/td&gt;
      &lt;td&gt;ACSM 2009: 3-5 minutes for advanced lifters training heavy&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Compound lifts, 6-12 reps (squat, bench, row, press)&lt;/td&gt;
      &lt;td&gt;2-3 min&lt;/td&gt;
      &lt;td&gt;ACSM 2009: at least 2-3 minutes for core lifts; 3 minutes beat 1 in a 2016 trial&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Isolation and machine work (curls, raises, leg extensions)&lt;/td&gt;
      &lt;td&gt;60-90 s&lt;/td&gt;
      &lt;td&gt;ACSM 2009: 1-2 minutes for assistance exercises; a 2024 meta-analysis saw no clear gain past 90 seconds&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;High-rep, endurance-focused sets&lt;/td&gt;
      &lt;td&gt;30-90 s&lt;/td&gt;
      &lt;td&gt;ACSM 2009: under 90 seconds for local muscular endurance&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Opposing-muscle supersets (row + press)&lt;/td&gt;
      &lt;td&gt;Rest after the pair&lt;/td&gt;
      &lt;td&gt;2025 meta-analysis: shorter sessions, similar volume and results&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Short on time&lt;/td&gt;
      &lt;td&gt;Cut isolation rest first, then add a set&lt;/td&gt;
      &lt;td&gt;2022 trial: growth tracked total volume, not rest length&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;In short: rest longer on the heavy lifts you do first, and on anything where your next set comes up well short of the last one. Rest less on small-muscle work, where shorter rest costs the fewest reps.&lt;/p&gt;

&lt;h2 id=&quot;what-does-the-research-say-about-rest-between-sets&quot;&gt;What does the research say about rest between sets?&lt;/h2&gt;

&lt;p&gt;The evidence has moved away from fixed prescriptions. Rest now looks like it matters mainly through the reps it lets you keep.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Source&lt;/th&gt;
      &lt;th&gt;What it compared&lt;/th&gt;
      &lt;th&gt;What it found&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://pubmed.ncbi.nlm.nih.gov/19204579/&quot;&gt;ACSM position stand, 2009&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;Guideline, not a single study&lt;/td&gt;
      &lt;td&gt;At least 2-3 min for heavy core lifts, 1-2 min for assistance work and for hypertrophy, 3-5 min for advanced heavy loading, under 90 s for endurance&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://pubmed.ncbi.nlm.nih.gov/26605807/&quot;&gt;Schoenfeld et al., 2016&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;1 vs 3 min rest, 21 trained men, 8 weeks&lt;/td&gt;
      &lt;td&gt;3 min gave larger squat and bench 1RM gains and more thigh muscle thickness; no difference in muscular endurance&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://pubmed.ncbi.nlm.nih.gov/28641044/&quot;&gt;Grgic et al., 2017&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;Review of 6 studies on hypertrophy&lt;/td&gt;
      &lt;td&gt;Short and long rest both build muscle; trained lifters may do better with longer rest&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://pubmed.ncbi.nlm.nih.gov/28933024/&quot;&gt;Grgic et al., 2018&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;Review of 23 studies on strength&lt;/td&gt;
      &lt;td&gt;Strength rises even with under 60 s; over 2 min looks best for trained lifters, 60-120 s is enough for untrained&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://www.frontiersin.org/journals/sports-and-active-living/articles/10.3389/fspor.2024.1429789/full&quot;&gt;Singer et al., 2024&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;Bayesian meta-analysis, 9 studies&lt;/td&gt;
      &lt;td&gt;Small hypertrophy benefit for rest over 60 s; no appreciable difference beyond 90 s&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://pmc.ncbi.nlm.nih.gov/articles/PMC12965823/&quot;&gt;ACSM overview of reviews, 2026&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;137 systematic reviews&lt;/td&gt;
      &lt;td&gt;Inter-set rest did not affect strength; not enough data to say whether it affects hypertrophy&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The 2016 trial is the one most often quoted, and it is a good one: trained men, 3 sets of 8-12 reps on seven exercises, three full-body sessions a week, and rest as the only difference between groups. Its limits are size and length. Twenty-one people over eight weeks can show a difference, but they cannot pin down a precise optimum.&lt;/p&gt;

&lt;p&gt;The 2026 ACSM document is the newest and the most cautious. Where the 2009 stand gave specific minutes, the 2026 review gives no rest recommendation at all, because across the reviews it covered, rest length was not a significant factor for strength and the hypertrophy data were too thin to call (&lt;a href=&quot;https://pmc.ncbi.nlm.nih.gov/articles/PMC12965823/&quot;&gt;Currier et al., 2026&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Rest still matters, though less than effort and total volume, and mostly through its effect on volume.&lt;/p&gt;

&lt;h2 id=&quot;why-does-longer-rest-help-when-it-does&quot;&gt;Why does longer rest help, when it does?&lt;/h2&gt;

&lt;p&gt;It keeps reps on the later sets. Rest a minute between heavy sets and the second and third sets usually come up short of the first. Over weeks, that is less total work.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://pubmed.ncbi.nlm.nih.gov/35622106/&quot;&gt;Longo et al. (2022)&lt;/a&gt; tested this directly. Twenty-eight people trained one leg at a time on knee extensions at 80% of one-rep max for ten weeks, with 1 or 3 minutes of rest and some protocols matched for total volume load. Quadriceps growth followed volume load: about 13% in the long-rest and volume-matched short-rest conditions, about 7% in the others. Strength rose similarly across all of them. The authors concluded that volume load drove the growth and the rest interval itself did not.&lt;/p&gt;

&lt;p&gt;Singer and colleagues read their 2024 meta-analysis the same way: the benefit of resting past 60 seconds is probably mediated by smaller losses in volume load, and those losses level off as rest gets longer.&lt;/p&gt;

&lt;p&gt;In practice, rest long enough that the next set is not cut short. If you rest less, for time or preference, add a set to make up the reps.&lt;/p&gt;

&lt;h2 id=&quot;how-do-you-shorten-a-workout-without-losing-much&quot;&gt;How do you shorten a workout without losing much?&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;Cut rest on isolation and machine work first. Curls, raises and leg extensions recover quickly between sets. Keep the longer rest on the first heavy compound lift of the day.&lt;/li&gt;
  &lt;li&gt;Pair opposing exercises. A &lt;a href=&quot;https://pubmed.ncbi.nlm.nih.gov/39903375/&quot;&gt;2025 meta-analysis in Sports Medicine&lt;/a&gt; found supersets cut session time while keeping total reps and volume load similar, with similar long-term strength and hypertrophy. Opposing pairs such as a row with a bench press kept volume best. Pairs with similar movements, such as bench press and dips, reduced it, and supersets in general felt harder and caused more fatigue.&lt;/li&gt;
  &lt;li&gt;Rest less and add a set. Longo’s volume-matched conditions show this works.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;should-you-time-your-rest-at-all&quot;&gt;Should you time your rest at all?&lt;/h2&gt;

&lt;p&gt;I think so, though the reason has little to do with physiology. Any progression rule that moves on reps assumes the reps are comparable from one session to the next. If Tuesday’s sets had two minutes between them and Friday’s had four because you were on your phone, the rep counts in your log are measuring the rest as much as the lifting. That matters most under &lt;a href=&quot;/journal/double-progression-explained/&quot;&gt;double progression&lt;/a&gt;, where the weight only goes up once every set reaches the top of the rep range.&lt;/p&gt;

&lt;p&gt;A timer keeps that variable fixed, and it stops rest creeping the other way on days when you are in a hurry.&lt;/p&gt;

&lt;p&gt;This is training information and not medical advice. If you have a heart condition or high blood pressure, or get dizzy during heavy sets, ask a clinician how to approach heavy lifting and rest.&lt;/p&gt;

&lt;h2 id=&quot;how-liftlog-times-rest&quot;&gt;How LiftLog times rest&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/apps/liftlog/&quot;&gt;LiftLog&lt;/a&gt; starts the rest timer when you log a working set. Warm-up sets do not trigger it, and neither do timed cardio sets. The timer draws as a ring and has buttons to add or remove 15 seconds or skip.&lt;/p&gt;

&lt;p&gt;The default is 90 seconds, with 30 seconds, 1, 2, 3 and 5 minutes available in settings. Each exercise in a program can carry its own rest, and you can change it for an exercise during a workout. The bundled example programs set rest per exercise along the lines of the table above: most heavy sets of five reps or fewer get 3 to 4 minutes, most sets of six to eleven get 1 to 2 minutes, and most high-rep work gets 45 to 60 seconds.&lt;/p&gt;

&lt;p&gt;For supersets and giant sets there is no rest between the exercises in a group. The timer starts after the last exercise of the round.&lt;/p&gt;

&lt;p&gt;The timer keeps counting if you lock the phone or switch apps. Sound, haptics and a rest-complete notification for when the phone is locked can each be turned off in settings. Programs and progression rules are covered in &lt;a href=&quot;/journal/choosing-a-strength-program-you-will-finish/&quot;&gt;choosing a strength program you will finish&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>When does Apple pay developers? The App Store fiscal calendar, payment dates and missing months</title>
    <link href="https://lagerland-apps.github.io/journal/when-does-apple-pay-developers/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/when-does-apple-pay-developers/</id>
    <published>2026-10-17T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Apple pays App Store developers once per fiscal month, and its fiscal months don&apos;t line up with the calendar. That one fact explains most of the confusion: the month with two deposits, the month with none, and the financial report that seems to cover the wrong dates.</summary>
    <content type="html">&lt;p&gt;Apple’s rule is one sentence long: payments are made “within 45 days of the last day of the fiscal month in which the transaction was completed,” to the bank account and currency you entered in App Store Connect (&lt;a href=&quot;https://developer.apple.com/help/app-store-connect/getting-paid/overview-of-receiving-payments/&quot;&gt;Apple&lt;/a&gt;). The fiscal month is the part that needs explaining, because it decides when a sale gets paid and which report it appears in.&lt;/p&gt;

&lt;h2 id=&quot;when-will-apple-pay-me&quot;&gt;When will Apple pay me?&lt;/h2&gt;

&lt;p&gt;To be paid at all, Apple lists four conditions (&lt;a href=&quot;https://developer.apple.com/help/app-store-connect/getting-paid/overview-of-receiving-payments/&quot;&gt;Apple&lt;/a&gt;):&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;A Paid Apps Agreement in effect.&lt;/li&gt;
  &lt;li&gt;Banking information in App Store Connect. Apple pays the primary account on file and doesn’t split payments across accounts.&lt;/li&gt;
  &lt;li&gt;Proceeds above the minimum payment threshold for each country or region where you sell.&lt;/li&gt;
  &lt;li&gt;Any monthly invoicing your country or region requires.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Tax forms belong on that list in practice: Apple’s tax pages say you need to submit them, alongside banking information, to receive payments (&lt;a href=&quot;https://developer.apple.com/help/app-store-connect/manage-tax-information/provide-tax-information/&quot;&gt;Apple&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Once those are in place, Apple’s bank combines the proceeds from every currency you sell in and sends “a single payment to your bank per fiscal month.”&lt;/p&gt;

&lt;h2 id=&quot;how-does-apples-fiscal-calendar-work&quot;&gt;How does Apple’s fiscal calendar work?&lt;/h2&gt;

&lt;p&gt;Fiscal months are built from whole weeks that run Sunday to Saturday. Each quarter has a five-week month followed by two four-week months, and the year ends in late September. Fiscal 2026 ended on Saturday, September 26. In 2026 the App Store’s fiscal quarters have closed on the same days as Apple’s company quarters; Apple’s third quarter of fiscal 2026 ended on June 27 (&lt;a href=&quot;https://www.apple.com/newsroom/2026/07/apple-reports-third-quarter-results/&quot;&gt;Apple&lt;/a&gt;), the same day as fiscal June.&lt;/p&gt;

&lt;p&gt;Apple’s help pages link to the official calendar inside App Store Connect, which needs a sign-in. These are the fiscal months behind this year’s payments, with the payment dates that RevenueCat and ASO.dev both list in their published calendars (&lt;a href=&quot;https://www.revenuecat.com/blog/app-store-fiscal-calendar-and-payment-dates&quot;&gt;RevenueCat&lt;/a&gt;, &lt;a href=&quot;https://aso.dev/app-store-connect/apple-fiscal-calendar/&quot;&gt;ASO.dev&lt;/a&gt;):&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Fiscal month&lt;/th&gt;
      &lt;th&gt;Sales period&lt;/th&gt;
      &lt;th&gt;Payment&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;November 2025&lt;/td&gt;
      &lt;td&gt;Nov 2 to Nov 29, 2025&lt;/td&gt;
      &lt;td&gt;Fri, Jan 2, 2026&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;December 2025&lt;/td&gt;
      &lt;td&gt;Nov 30 to Dec 27, 2025&lt;/td&gt;
      &lt;td&gt;Thu, Jan 29&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;January 2026 (5 weeks)&lt;/td&gt;
      &lt;td&gt;Dec 28, 2025 to Jan 31&lt;/td&gt;
      &lt;td&gt;Thu, Mar 5&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;February 2026&lt;/td&gt;
      &lt;td&gt;Feb 1 to Feb 28&lt;/td&gt;
      &lt;td&gt;Thu, Apr 2&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;March 2026&lt;/td&gt;
      &lt;td&gt;Mar 1 to Mar 28&lt;/td&gt;
      &lt;td&gt;Thu, Apr 30&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;April 2026 (5 weeks)&lt;/td&gt;
      &lt;td&gt;Mar 29 to May 2&lt;/td&gt;
      &lt;td&gt;Thu, Jun 4&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;May 2026&lt;/td&gt;
      &lt;td&gt;May 3 to May 30&lt;/td&gt;
      &lt;td&gt;Thu, Jul 2&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;June 2026&lt;/td&gt;
      &lt;td&gt;May 31 to Jun 27&lt;/td&gt;
      &lt;td&gt;Thu, Jul 30&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;July 2026 (5 weeks)&lt;/td&gt;
      &lt;td&gt;Jun 28 to Aug 1&lt;/td&gt;
      &lt;td&gt;Thu, Sep 3&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;August 2026&lt;/td&gt;
      &lt;td&gt;Aug 2 to Aug 29&lt;/td&gt;
      &lt;td&gt;Thu, Oct 1&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;September 2026&lt;/td&gt;
      &lt;td&gt;Aug 30 to Sep 26&lt;/td&gt;
      &lt;td&gt;Thu, Oct 29 (expected)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;October 2026 (5 weeks)&lt;/td&gt;
      &lt;td&gt;Sep 27 to Oct 31&lt;/td&gt;
      &lt;td&gt;Thu, Dec 3 (expected)&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The pattern is 33 days from the Saturday a fiscal month ends to a Thursday payment, with New Year’s Day pushing one payment to a Friday. That sits inside Apple’s 45-day promise, but Apple only promises the 45 days. The Thursday is only the pattern so far. Treat the last two rows as estimates until Payments and Financial Reports shows an expected payment date.&lt;/p&gt;

&lt;p&gt;A fiscal month can also carry a calendar month’s name while starting in the previous one. Fiscal January 2026 began on December 28, 2025, so a purchase on December 30 sits in a January financial report. Sales and Trends, which uses calendar days in Pacific Time, files the same purchase under December.&lt;/p&gt;

&lt;h2 id=&quot;why-is-a-month-missing&quot;&gt;Why is a month missing?&lt;/h2&gt;

&lt;p&gt;Most of the time, nothing is wrong. Because every quarter starts with a five-week month, payments drift against the calendar. In 2026, January, April, July and October each had two payments, and February, May and August had none. If your bookkeeping runs by calendar month, those months will look empty even though every fiscal month was paid.&lt;/p&gt;

&lt;p&gt;When a fiscal month really wasn’t paid, Payments and Financial Reports says why (&lt;a href=&quot;https://developer.apple.com/help/app-store-connect/getting-paid/view-payments-and-proceeds&quot;&gt;Apple&lt;/a&gt;):&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Expected Payment Date: the payment date hasn’t come yet.&lt;/li&gt;
  &lt;li&gt;Balance Carried Forward: proceeds haven’t reached the minimum payment threshold and “will carry over to the next payment period.”&lt;/li&gt;
  &lt;li&gt;Payment Returned: your bank sent the payment back. App Store Connect shows the reason and a Transaction ID. Once you fix the banking details, Apple says returned earnings can take up to two regular payment cycles to resend.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are two quieter cases. A fiscal month with no purchases or refunds produces no financial report at all (&lt;a href=&quot;https://developer.apple.com/help/app-store-connect/getting-paid/download-financial-reports/&quot;&gt;Apple&lt;/a&gt;), and an expired agreement or missing tax form stops payments until it is fixed.&lt;/p&gt;

&lt;h2 id=&quot;what-is-the-minimum-payment-threshold&quot;&gt;What is the minimum payment threshold?&lt;/h2&gt;

&lt;p&gt;Apple publishes a &lt;a href=&quot;https://developer.apple.com/help/app-store-connect/reference/reporting/minimum-payment-threshold&quot;&gt;table of thresholds&lt;/a&gt; by bank country and account currency. Many common pairs, such as a USD account in the United States, a EUR account in the euro area or a GBP account in the United Kingdom, are listed at 0.02 USD. Any bank country or currency not in the table must exceed 40 USD. A small app paid into an unlisted currency can carry its balance forward for months before a payment goes out.&lt;/p&gt;

&lt;h2 id=&quot;what-currency-are-you-paid-in-and-who-takes-the-fees&quot;&gt;What currency are you paid in, and who takes the fees?&lt;/h2&gt;

&lt;p&gt;You are paid in your bank account’s currency. Apple’s bank does the conversion, typically at the spot rate on the payment date and no more than three business days before the money reaches your account (&lt;a href=&quot;https://developer.apple.com/help/app-store-connect/getting-paid/overview-of-receiving-payments/&quot;&gt;Apple&lt;/a&gt;). Apple sends low-value transfers instead of wires where it can, but your bank or an intermediary bank may still deduct fees, and the deposit can be smaller than the amount App Store Connect shows.&lt;/p&gt;

&lt;p&gt;That is why the estimate and the payment differ. Before a month is paid, App Store Connect shows Total Estimated Proceeds, and Apple says the actual amount can differ mainly because of exchange-rate movement and withholding tax, which is applied when the payment is made (&lt;a href=&quot;https://developer.apple.com/help/app-store-connect/getting-paid/view-payments-and-proceeds&quot;&gt;Apple&lt;/a&gt;).&lt;/p&gt;

&lt;h2 id=&quot;where-do-you-see-payments-in-app-store-connect&quot;&gt;Where do you see payments in App Store Connect?&lt;/h2&gt;

&lt;p&gt;Payments and Financial Reports, which needs the Account Holder, Admin or Finance role. Payment information for the previous fiscal month starts to appear on the first Wednesday of the current fiscal month, and the financial reports for every country and region are ready by the first Friday (&lt;a href=&quot;https://developer.apple.com/help/app-store-connect/getting-paid/view-payments-and-proceeds&quot;&gt;Apple&lt;/a&gt;). You can ask for an email when they arrive.&lt;/p&gt;

&lt;p&gt;A paid month shows the amount in your bank currency, the bank name with the last four digits of the account, the issue date and a seven-digit Transaction ID, also called a Consolidated Credit Identifier. Have that ID ready if you need to ask Apple or your bank about a deposit. For any country or region you can open units, amounts in the local currency, taxes and adjustments, and the exchange rate applied.&lt;/p&gt;

&lt;p&gt;The downloadable financial reports come as a single file for all countries and regions, as separate files for each location, or as a detailed version with transaction and settlement dates, and Apple keeps them for ten years. They can also be fetched through the App Store Connect API.&lt;/p&gt;

&lt;h2 id=&quot;why-doesnt-the-payment-match-sales-and-trends&quot;&gt;Why doesn’t the payment match Sales and Trends?&lt;/h2&gt;

&lt;p&gt;Sales and Trends counts a purchase when the customer starts it and estimates USD amounts with last month’s average exchange rates. The financial reports count settled transactions in fiscal months and use the rate applied to your bank’s currency. My &lt;a href=&quot;/journal/app-store-proceeds-vs-sales/&quot;&gt;July post on proceeds and sales&lt;/a&gt; goes through every column and the reasons the two sets of numbers drift apart.&lt;/p&gt;

&lt;h2 id=&quot;where-appmeta-pulse-fits&quot;&gt;Where AppMeta Pulse fits&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/apps/appmeta-pulse/&quot;&gt;AppMeta Pulse&lt;/a&gt; reads the daily Sales and Trends reports through the App Store Connect API. It doesn’t read Payments and Financial Reports, so it can’t tell you when a payment will land or what it will be after conversion and fees. For that, the Payments page above is the source.&lt;/p&gt;

&lt;p&gt;Payments and Financial Reports is still the first place Pulse sends you: the Vendor Number it needs to download sales reports is shown there, under your legal entity name. After that, Pulse covers the daily side, with proceeds and downloads by app, net of refunds, and subscription figures such as the &lt;a href=&quot;/journal/how-to-calculate-mrr-for-app-store-subscriptions/&quot;&gt;MRR worked out from Apple’s Subscription report&lt;/a&gt;. It also keeps its own copy of the daily reports after Apple’s one-year window for them closes.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>When to deload: the signs, the common schemes, and how good the evidence really is</title>
    <link href="https://lagerland-apps.github.io/journal/when-to-deload/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/when-to-deload/</id>
    <published>2026-10-14T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">A deload is the week most lifters plan and few can explain. Everyone agrees you take one; the arguments are about when, what you cut, and whether it does anything at all. The evidence so far is a consensus of coaches, a large survey of athletes and a small number of controlled trials. That is enough for practical answers, as long as you know which kind of answer you are getting.</summary>
    <content type="html">&lt;p&gt;A deload is a short, planned stretch of easier training, usually about a week, taken to shed fatigue before you push again. The common version keeps your exercises and training days and changes three things:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Fewer sets, often roughly half.&lt;/li&gt;
  &lt;li&gt;Lighter loads, especially on the big multi-joint lifts.&lt;/li&gt;
  &lt;li&gt;More reps in reserve: you stop each set further from failure.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When to take one is the harder question, and the research and the people who coach for a living answer it below.&lt;/p&gt;

&lt;h2 id=&quot;what-is-a-deload-by-definition&quot;&gt;What is a deload, by definition?&lt;/h2&gt;

&lt;p&gt;Until recently there wasn’t an agreed definition. In 2023, Bell and colleagues ran a &lt;a href=&quot;https://pmc.ncbi.nlm.nih.gov/articles/PMC10511399/&quot;&gt;Delphi consensus&lt;/a&gt; with expert strength and physique coaches over three rounds (34 coaches started, 21 finished). The definition they arrived at describes a deload as a period of reduced training stress designed to reduce fatigue, promote recovery and prepare the athlete for the training that follows. They separated it from a taper, which is about peaking for a competition.&lt;/p&gt;

&lt;p&gt;The panel agreed on surprisingly little beyond that. Reducing volume was the only point with universal agreement. Intensity could go down, stay the same, or even rise, depending on the athlete and the sport. Deloads could be planned in advance, triggered by how the athlete feels, or both.&lt;/p&gt;

&lt;h2 id=&quot;what-are-the-signs-you-need-a-deload&quot;&gt;What are the signs you need a deload?&lt;/h2&gt;

&lt;p&gt;The best data on real-world triggers comes from &lt;a href=&quot;https://pmc.ncbi.nlm.nih.gov/articles/PMC10948666/&quot;&gt;Rogerson and colleagues’ 2024 survey&lt;/a&gt; of 246 competitive strength and physique athletes, most of them powerlifters.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Trigger&lt;/th&gt;
      &lt;th&gt;Athletes who used it&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;The program specifies a deload&lt;/td&gt;
      &lt;td&gt;65.4%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Feeling beaten up (soreness, joint aches, pain)&lt;/td&gt;
      &lt;td&gt;62.6%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Performance stalls or drops&lt;/td&gt;
      &lt;td&gt;54.1%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Previous injuries flare up&lt;/td&gt;
      &lt;td&gt;31.3%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;High stress outside training&lt;/td&gt;
      &lt;td&gt;30.5%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Holiday or travel&lt;/td&gt;
      &lt;td&gt;24.4%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Not feeling like training&lt;/td&gt;
      &lt;td&gt;14.6%&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Turned into something you can check on a Sunday evening, the signs worth watching are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Several lifts have stopped moving at once. One stalled lift usually needs a programming change. Three stalled lifts at the same time point at fatigue.&lt;/li&gt;
  &lt;li&gt;Your usual weights rate harder. If a load that was an RPE 7 a month ago now feels like an 8.5, on several lifts, for more than one session, that is a recovery signal. &lt;a href=&quot;/journal/rpe-and-rir-explained/&quot;&gt;How RPE and reps in reserve work&lt;/a&gt; covers how to rate that honestly.&lt;/li&gt;
  &lt;li&gt;Joints and tendons ache before the session starts, not just after it.&lt;/li&gt;
  &lt;li&gt;Life outside the gym is taking more than usual: a heavy work stretch, a new baby, bad sleep.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One of these on its own is a bad week. Two or more together for a week or longer is what most deload rules are written for.&lt;/p&gt;

&lt;p&gt;A note on pain: a deload is for fatigue. Pain that is sharp, localised or getting worse is a different problem, and the right person to see about it is a clinician, not your program.&lt;/p&gt;

&lt;h2 id=&quot;how-do-you-run-a-deload&quot;&gt;How do you run a deload?&lt;/h2&gt;

&lt;p&gt;There are four common shapes. Most real deloads combine the first three.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Scheme&lt;/th&gt;
      &lt;th&gt;What changes&lt;/th&gt;
      &lt;th&gt;What stays the same&lt;/th&gt;
      &lt;th&gt;Where it fits&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Volume deload&lt;/td&gt;
      &lt;td&gt;Fewer sets, often about half; sometimes fewer reps per set&lt;/td&gt;
      &lt;td&gt;Exercises, training days, loads close to normal&lt;/td&gt;
      &lt;td&gt;High-volume and hypertrophy-focused training&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Intensity deload&lt;/td&gt;
      &lt;td&gt;Lighter loads&lt;/td&gt;
      &lt;td&gt;Sets, reps, exercises&lt;/td&gt;
      &lt;td&gt;Heavy, low-rep strength phases&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Effort deload&lt;/td&gt;
      &lt;td&gt;Stop further from failure, more reps in reserve&lt;/td&gt;
      &lt;td&gt;Program structure&lt;/td&gt;
      &lt;td&gt;Programs written in RPE or RIR&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Week off&lt;/td&gt;
      &lt;td&gt;No lifting at all&lt;/td&gt;
      &lt;td&gt;Nothing, apart from walking or other sport&lt;/td&gt;
      &lt;td&gt;Travel, illness, or when you need a mental break&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The survey shows what athletes actually do. During a deload, 78.9% cut their weekly sets and 52.8% cut reps per set. On multi-joint lifts, 83.7% used lighter loads and 84.9% stopped further from failure. Meanwhile 63.0% kept the same number of sessions per week, and 70.3% kept the same multi-joint exercises. The pattern is clear enough to copy: same days, same main lifts, less of everything.&lt;/p&gt;

&lt;p&gt;Some programs build the deload into the structure. 5/3/1’s fourth week is one, as the table in &lt;a href=&quot;/journal/choosing-a-strength-program-you-will-finish/&quot;&gt;the program-choosing post&lt;/a&gt; shows.&lt;/p&gt;

&lt;h2 id=&quot;how-often-should-you-deload&quot;&gt;How often should you deload?&lt;/h2&gt;

&lt;p&gt;The survey’s athletes deloaded every 5.6 weeks on average, with a spread of plus or minus 2.3 weeks and a range from 1 to 12, and each deload lasted about 6.4 days. The Delphi paper describes pre-planned deloads every 4 to 8 weeks as common practice, while its panel declined to set a fixed interval and said frequency should follow how the athlete responds.&lt;/p&gt;

&lt;p&gt;Planning one every 4 to 6 weeks and moving it when the signs above show up is a reasonable default. Bring it forward when several signs line up early; push it back a week when training is going well and nothing aches. A deload taken because the calendar said so, in a week when you feel great, costs you little, but it isn’t buying much either.&lt;/p&gt;

&lt;h2 id=&quot;what-does-the-evidence-actually-show&quot;&gt;What does the evidence actually show?&lt;/h2&gt;

&lt;p&gt;Less than the confidence of most gym advice would suggest. Most of what we know is expert opinion (the Delphi panel) and self-report (the survey), and the survey’s own authors call their findings broad guidelines until experiments test whether deloading helps. In that survey, 65.0% of athletes said they felt they could progress without deloading at all.&lt;/p&gt;

&lt;p&gt;The controlled trials so far are small:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://pmc.ncbi.nlm.nih.gov/articles/PMC10809978/&quot;&gt;Coleman and colleagues (2024)&lt;/a&gt; had 39 resistance-trained adults run a 9-week, high-volume program. One group took the whole of week 5 off. Muscle growth, power and local endurance came out about the same in both groups. The group that trained straight through gained somewhat more lower-body strength (squat 1RM rose by about 16 kg against 13 kg), though the statistical uncertainty around that difference included zero. Note that this was a full week off, not a reduced-load deload.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://pmc.ncbi.nlm.nih.gov/articles/PMC13031491/&quot;&gt;Pancar and colleagues (2026)&lt;/a&gt; trained 19 untrained young men, with each person’s arms and legs randomly assigned to continuous training or to a deload of one session and two sets per exercise in weeks 4 and 8. Muscle thickness and 10-rep strength improved similarly under both conditions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Put together: a well-run deload doesn’t appear to cost muscle, a complete week off may cost a little top-end strength, and no trial I know of has shown that deloads make you stronger over the long run. They remain a sensible way to manage fatigue and to make hard training sustainable. Treat any deload schedule as a starting point you adjust.&lt;/p&gt;

&lt;h2 id=&quot;how-gymlogger-x-schedules-deloads-and-flags-plateaus&quot;&gt;How GymLogger X schedules deloads and flags plateaus&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/apps/gymlogger-x/&quot;&gt;GymLogger X&lt;/a&gt; handles deloads in three places.&lt;/p&gt;

&lt;p&gt;In the programs it builds, the Smart Program Creator schedules a deload week every 4 weeks for beginners, every 5 for intermediates and every 6 for advanced lifters in linear, undulating and wave programs. Block programs end each block with one. A deload week halves the sets (never below one per exercise), keeps the rep ranges, and raises the reps-in-reserve target, by three in most program styles, so the loads come down with the effort. That matches what most of the surveyed athletes did.&lt;/p&gt;

&lt;p&gt;In your history, sessions logged during a program’s deload week are marked as deloads automatically, and any other session can be marked as one from its menu. The flag matters because a light week would otherwise drag down your strength trend and your weekly set counts. The app also notices unplanned deloads: if your weekly training volume falls by 30% or more after two hard weeks, the recovery screen marks that week on its load chart and tells you how long ago your last deload was.&lt;/p&gt;

&lt;p&gt;In the plateau rule, a Pro feature, deload sessions are dropped before the rule runs, so a deliberately light week can’t create a false stall. Detection stays off for your first 12 weeks of logged training and needs at least eight sessions on a lift, or five if you train it rarely. It then fits a trend through the estimated 1RM of your four most recent sessions on that lift, using the Epley formula from &lt;a href=&quot;/journal/how-to-estimate-your-one-rep-max/&quot;&gt;the one-rep max post&lt;/a&gt;, and compares it with a threshold built from your own rate of gain over the last 90 days, kept between 0.05% and 1% per session. If the trend misses that bar while volume hasn’t dropped by more than 3%, three sessions earn a Monitoring flag. A confirmed plateau needs four, plus either a fatigue sign (training the lift twice in a week, on back-to-back days, or with volume rising while strength stays flat) or at least six non-deload sessions logged on that lift, and a confidence score of at least 0.4.&lt;/p&gt;

&lt;p&gt;A confirmed flag lists a likely cause and two suggestions. When volume has been climbing, it suggests cutting volume by about 20% or taking a deload week; when the cause is unclear, it suggests a deload week or a change of rep range. It doesn’t move your program for you. Whether this is the week to deload is still your call, and the signs above are the ones I’d check first.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>Designing a puzzle with no words: how Tare teaches its rules, and what accessibility took</title>
    <link href="https://lagerland-apps.github.io/journal/wordless-puzzle-game-design/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/wordless-puzzle-game-design/</id>
    <published>2026-10-09T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Tare has 200 levels and not one word on the playing field: no tutorial screen, no arrows, no “drag here”. The puzzle had to teach itself, and with no text to label, accessibility had to reach the board itself. This post covers what the first levels teach and how, then what it took to make the same puzzle work with VoiceOver, high contrast and large type.</summary>
    <content type="html">&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Update, version 1.1:&lt;/strong&gt; Tare now has 200 levels in ten chapters of twenty. Chapter I, onboarding included, is still free, and one purchase unlocks the other 180. This post is the launch-day essay, written when Tare had 80 levels.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Every level of &lt;a href=&quot;/apps/tare/&quot;&gt;Tare&lt;/a&gt; is a hanging mobile that you balance with numbered weights, and none of the 200 has a word on the playing field. There is no tutorial screen, hand icon or arrow. The puzzle had to teach the rule, the hidden weights and the cards that reveal them on its own. And because there is no text to label, accessibility couldn’t be a layer of button labels added at the end.&lt;/p&gt;
&lt;h2 id=&quot;what-the-first-levels-teach-and-how&quot;&gt;What the first levels teach, and how&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;You need to know&lt;/th&gt;
      &lt;th&gt;How Tare shows it&lt;/th&gt;
      &lt;th&gt;Level&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Level and still means solved&lt;/td&gt;
      &lt;td&gt;One piece in the tray, one empty hook. The only move balances the beam, and its pivot flashes as it crosses level&lt;/td&gt;
      &lt;td&gt;1&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Every hook takes a piece&lt;/td&gt;
      &lt;td&gt;Two hooks, two equal 3s&lt;/td&gt;
      &lt;td&gt;2&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;The heavy side drops, and distance multiplies&lt;/td&gt;
      &lt;td&gt;A 2 and a 4 for notches 2 and 1. With the 4 far out the beam tips; swapped, 2 × 2 = 4 × 1&lt;/td&gt;
      &lt;td&gt;3&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;The hook matters as much as the piece&lt;/td&gt;
      &lt;td&gt;A 3 already hangs three notches out; a 2 and two 1s must fill notches 1, 2 and 3 on the other arm&lt;/td&gt;
      &lt;td&gt;4&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Anything hung can be moved&lt;/td&gt;
      &lt;td&gt;A 4 starts on the wrong hook and has to come off&lt;/td&gt;
      &lt;td&gt;5&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;A hanging beam pulls with everything below it&lt;/td&gt;
      &lt;td&gt;The first nested beam: a 1 three notches out balances a small beam carrying 3&lt;/td&gt;
      &lt;td&gt;7&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;A card is a true statement&lt;/td&gt;
      &lt;td&gt;Two different shapes, both 4s, level on a card above a lever the card doesn’t picture&lt;/td&gt;
      &lt;td&gt;10&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;A beam with a secret won’t tell you&lt;/td&gt;
      &lt;td&gt;A “?” starts hung, and its beam sways instead of tilting&lt;/td&gt;
      &lt;td&gt;11&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;The sway climbs&lt;/td&gt;
      &lt;td&gt;A “?” on a lower beam makes the beam above it sway too&lt;/td&gt;
      &lt;td&gt;13&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Two signals run through every level.&lt;/p&gt;

&lt;p&gt;Every known weight states its value twice, as a numeral and as domino pips, and its size grows with its weight: 32 points across for a 1, 96 for a 9. A hidden “?” is always 52 points, whatever it weighs.&lt;/p&gt;

&lt;p&gt;A full but wrong board shudders once, a damped 1.2° shake over half a second with a soft haptic. There is no red, no buzzer and no failure screen. A drop that misses every hook doesn’t even get a shudder; the piece glides back to its slot.&lt;/p&gt;

&lt;h2 id=&quot;levels-with-one-way-forward&quot;&gt;Levels with one way forward&lt;/h2&gt;

&lt;p&gt;The rule for the first five levels was no text, no hand icons and no tutorial overlay. Each level offers so little that the next thing to try is the lesson. Level 1 has exactly one possible move, and it solves the level. By level 5 you have dragged, filled, swapped and re-hung, because level 5 can’t be solved without moving the piece it starts with.&lt;/p&gt;

&lt;p&gt;Three wordless helpers sit around those levels:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Live tilt preview. Hold a weight over a hook and the whole mobile leans to where it would rest if you let go.&lt;/li&gt;
  &lt;li&gt;A teaching line, on levels 1 to 5 only. After 15 seconds without a touch, a faint line arcs from a piece to a hook. It shows a move, not the solution.&lt;/li&gt;
  &lt;li&gt;A short introduction for each kind of card. The first time a card appears, and again for the first secret, tilt, sum and ratio, the room dims on the card and the pieces it quotes, a line joins them, and one piece lifts once. There are at most five in the whole game, and none is saved: the game works out what you’ve seen from the levels you’ve solved.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From then on, picking up a piece lifts every card that mentions it, so the shape of the piece is the pointer.&lt;/p&gt;

&lt;h2 id=&quot;no-channel-leaks-a-hidden-weight&quot;&gt;No channel leaks a hidden weight&lt;/h2&gt;

&lt;p&gt;The deduction only works if the game keeps its own secrets. A beam carrying an unsolved “?” sways about 3° either side of level and never settles, because, as the design notes put it, “the scale cannot weigh a secret”. &lt;a href=&quot;/journal/how-to-solve-balance-puzzles/&quot;&gt;How to solve a balance puzzle&lt;/a&gt; explains why that matters. The same rule holds on every other channel. The “?” bubble is one fixed size. With Sound on, each weight has its own note, and heavier is lower, but a “?” makes an unpitched thud. A “?” always gives the same haptic strength. VoiceOver calls it “hidden teal drop” and never says a number, and its beam “cannot settle, hidden weight”.&lt;/p&gt;

&lt;h2 id=&quot;what-accessibility-took&quot;&gt;What accessibility took&lt;/h2&gt;

&lt;p&gt;With no words on the canvas, labelling the buttons covers almost nothing, so the board itself had to become something a screen reader can walk.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Need&lt;/th&gt;
      &lt;th&gt;What Tare does&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Playing without sight&lt;/td&gt;
      &lt;td&gt;VoiceOver reads the mobile as a tree: “Beam 2, hanging from Beam 1, left, notch 2.” A hook says what hangs on it or “empty hook”. Select a piece and every hook offers “Place the…”; a hung piece offers “Return to tray”. Each beam reports balanced, which side is heavier, or that it cannot settle. Cards read as sentences: “Reference scale, level. Left, notch 1: …”&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Colour blindness&lt;/td&gt;
      &lt;td&gt;Colour never carries meaning alone. Each of the ten shapes has one colour, and every known weight shows its numeral and pips&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Low vision&lt;/td&gt;
      &lt;td&gt;Numerals and pips clear 3:1 by default. The High contrast switch, or the system’s Increase Contrast, swaps in flat fills that clear 4.5:1&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Large text&lt;/td&gt;
      &lt;td&gt;The numeral grows with Dynamic Type; at the accessibility sizes it gives way to the pips instead of overflowing a small piece&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Motion sensitivity&lt;/td&gt;
      &lt;td&gt;Reduce Motion stops the idle drift and the tilt parallax, and turns the sway into a slow pulse in opacity, which keeps the meaning without the movement&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Transparency&lt;/td&gt;
      &lt;td&gt;Reduce Transparency swaps the glassy bubble for a matte one with a dashed rim, at the same fixed size&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Precise touch&lt;/td&gt;
      &lt;td&gt;A hook catches a piece from 60 points away, every piece has a touch target of at least 48 points, and a tap sends a hung piece home&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Sound and haptics&lt;/td&gt;
      &lt;td&gt;Sound ships off, and no level needs it. The Haptics switch appears only on devices that have haptics, so not on iPads&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Tests check all of this. One fills every hook of every shipped level using voice actions alone. Another plays levels 1 to 3 as a player who cannot see the screen: it knows only what an empty hook and a level beam sound like, and how to put a piece back. Others recompute every contrast ratio when the tests run, and check that two pieces share a colour only when they share a shape.&lt;/p&gt;

&lt;h2 id=&quot;where-the-words-went&quot;&gt;Where the words went&lt;/h2&gt;

&lt;p&gt;Tare does use words in places. Settings, the four chapter names (The Hang, The Secret, The Cascade, The Exhibition), the four world names and the unlock screen all have them. The app’s whole string catalog is 108 entries, and about two-thirds of them exist only for VoiceOver.&lt;/p&gt;

&lt;p&gt;A test keeps the canvas to its rule: it reads the code that draws a level and fails if it finds any text other than a weight’s numeral and the “?”.&lt;/p&gt;

&lt;p&gt;The plan had been English-only VoiceOver at launch, on the reasoning that the gameplay is wordless. That holds for the canvas, but for a player who can’t see it, the spoken clauses are the game, and shipping an English game inside a store listing written in 50 locales was where the wordless argument broke down. On 20 September I made the whole app ship in all 50 locales. Every spoken line was already a whole clause with placeholders, so a translator could reorder it.&lt;/p&gt;

&lt;p&gt;Right-to-left languages turned up a different problem. In Arabic, Hebrew and Urdu, SwiftUI mirrored the drawing of the mobile but not the drag, so a player had to touch the mirror image of a piece to lift it. A mobile is a physical toy, so it is now drawn left to right in every language while the menus mirror, and VoiceOver’s “left arm” matches what’s on screen.&lt;/p&gt;

&lt;h2 id=&quot;decisions-that-changed-late&quot;&gt;Decisions that changed late&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Sound off by default, 20 September. I played the finished build and didn’t want its sounds on unless a player asks. That cost a teaching channel, since the notes taught weight by ear. Level 1’s lesson now rests on the beam going level and still, which works because the level allows no other action.&lt;/li&gt;
  &lt;li&gt;The idle line became a teacher only, 19 September. It used to appear by itself after 8 seconds on every level, and it made levels too easy. Now it appears unasked only on levels 1 to 5. Elsewhere, hints are a Settings switch, off by default: each press draws one line from the next piece to its hook, never for the last piece, and the first press on an attempt costs that attempt’s third star.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tare is a free download for iPhone and iPad on iOS and iPadOS 18 or later. Chapter I’s 20 levels, onboarding included, are free to keep, and one $2.99 purchase unlocks the other 180; &lt;a href=&quot;/journal/puzzle-game-no-ads-one-purchase/&quot;&gt;why it is priced that way&lt;/a&gt; is its own post. If you came for the rule-learning, compare &lt;a href=&quot;/alternatives/baba-is-you/&quot;&gt;Baba Is You&lt;/a&gt;, whose rules are built out of word blocks, and &lt;a href=&quot;/alternatives/dragonbox-algebra/&quot;&gt;DragonBox Algebra&lt;/a&gt;, which also teaches through balancing. For the wider field, see &lt;a href=&quot;/guides/best-logic-puzzle-games-iphone/&quot;&gt;the best logic puzzle games for iPhone&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>No ads, no subscription: why Tare is free to start and $2.99 once</title>
    <link href="https://lagerland-apps.github.io/journal/puzzle-game-no-ads-one-purchase/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/puzzle-game-no-ads-one-purchase/</id>
    <published>2026-10-09T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Tare is out today as a free download. Chapter I&apos;s 20 levels are free for good, and one $2.99 purchase opens the rest (60 levels at launch, 180 since the ten-chapter update). There are no ads or subscriptions and nothing else to buy. Below is the whole model in one table, the paid-app plan it replaced, and the story of a purchase so quiet that App Review couldn&apos;t find it.</summary>
    <content type="html">&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Update, version 1.1:&lt;/strong&gt; Tare now has 200 levels in ten chapters of twenty. Chapter I is still free, and the one purchase now unlocks Chapters II to X, the other 180 levels. This post is the launch-day record of version 1.0, which had 80 levels, so the table, button names and chapter numbers below describe Chapters II to IV.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;/apps/tare/&quot;&gt;Tare&lt;/a&gt; is out today, and the price fits in a sentence: the download and the first 20 levels are free for good, and one $2.99 purchase opens the other 60. There are no ads or subscriptions and nothing else to buy.&lt;/p&gt;

&lt;p&gt;The full model comes first, then how it ended up this way, including the paid-app plan it replaced and the purchase App Review couldn’t find.&lt;/p&gt;

&lt;h2 id=&quot;whats-free-whats-p_iaptare-full-accesstare-and-whats-never-sold&quot;&gt;What’s free, what’s $2.99, and what’s never sold&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; &lt;/th&gt;
      &lt;th&gt;What it is&lt;/th&gt;
      &lt;th&gt;Cost&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;The download&lt;/td&gt;
      &lt;td&gt;The game, Settings, and every accessibility option&lt;/td&gt;
      &lt;td&gt;Free&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Chapter I · The Hang&lt;/td&gt;
      &lt;td&gt;20 levels: the wordless onboarding, the first nested beams, the first hidden weights and cards&lt;/td&gt;
      &lt;td&gt;Free for good, not a trial, never gated&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Chapters II to IV&lt;/td&gt;
      &lt;td&gt;60 levels: The Secret, The Cascade and The Exhibition, in three more worlds&lt;/td&gt;
      &lt;td&gt;$2.99 once, one non-consumable, Family Sharing on&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Hints&lt;/td&gt;
      &lt;td&gt;Off until you switch them on in Settings&lt;/td&gt;
      &lt;td&gt;Never money. The first hint on an attempt costs that attempt’s third star&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Stars and chapter canvases&lt;/td&gt;
      &lt;td&gt;Earned by playing. Finishing a chapter lets you pick its world as the backdrop for the whole game&lt;/td&gt;
      &lt;td&gt;Never sold&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Ads, subscriptions, consumables, lives, energy, timers&lt;/td&gt;
      &lt;td&gt;None&lt;/td&gt;
      &lt;td&gt;n/a&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The unlock screen gets its price from the App Store, so it shows your own currency. $2.99 is the US base, and Apple sets the equivalent in every other storefront. No price is written into the app anywhere.&lt;/p&gt;

&lt;h2 id=&quot;where-the-offer-appears-and-where-it-doesnt&quot;&gt;Where the offer appears, and where it doesn’t&lt;/h2&gt;

&lt;p&gt;You can open the purchase from three places:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;the Open Chapters II-IV button under Chapter I on the chapter wall, which carries no price;&lt;/li&gt;
  &lt;li&gt;any unlit level of Chapters II to IV;&lt;/li&gt;
  &lt;li&gt;the same button in Settings, directly above Restore purchases.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It never opens by itself, whether at launch, when you come back, after a solve, or over the celebration when you finish Chapter I. In that last case the wall simply returns with the button in view. Nothing inside a level advertises, and the pause menu has no offer. The unlock isn’t a promoted purchase on the App Store page either, since that would sell it to someone who has never hung a weight.&lt;/p&gt;

&lt;p&gt;Levels in chapters you haven’t bought are drawn in full but darkened, with no padlock. In Tare a padlock means that playing on will open a level, and playing alone will never open a chapter you haven’t bought. For the same reason VoiceOver says “not purchased” and never “locked”. The unlock screen doesn’t show your star total either, because a total next to a Buy button looks like something being priced, and nothing in the game is gated on stars.&lt;/p&gt;

&lt;h2 id=&quot;the-plan-before-this-one&quot;&gt;The plan before this one&lt;/h2&gt;

&lt;p&gt;Until 2 September, Tare was going to be a paid app: $3.99 up front, with “In-App Purchases: none” on the store page. The reasoning was about strangers judging six screenshots. A solo developer with no track record can’t ask much of someone deciding that way.&lt;/p&gt;

&lt;p&gt;On 1 September I played the first two finished chapters and found every level a single flat beam, which &lt;a href=&quot;/journal/how-to-solve-balance-puzzles/&quot;&gt;the post on solving balance puzzles&lt;/a&gt; covers. The next day, while rebuilding the 80-level arc, I made Chapter I free and put Chapters II to IV behind one purchase.&lt;/p&gt;

&lt;p&gt;A free chapter settles the screenshot question. By the time anyone sees the price, they have solved twenty levels, read their first picture cards and watched a “?” open. The launch plan now leaves the persuading to the free chapter instead of the price tag. The store description says exactly what’s free in its second line, because a free listing that doesn’t say so reads like a demo.&lt;/p&gt;

&lt;h2 id=&quot;why-p_iaptare-full-accesstare-and-why-it-wont-be-on-sale&quot;&gt;Why $2.99, and why it won’t be on sale&lt;/h2&gt;

&lt;p&gt;$2.99 is the lowest price that, by the launch plan’s judgement, still reads as something crafted and not a trinket. It is set once in US dollars, with worldwide automatic pricing.&lt;/p&gt;

&lt;p&gt;There is no launch discount, and the plan rules out discounts for the first year. It reckons that no price below $2.99 would earn back what it costs in credibility. For the first year at least, that also means nobody who buys early pays more than someone who waits for a sale.&lt;/p&gt;

&lt;h2 id=&quot;why-no-ads-subscription-or-consumables&quot;&gt;Why no ads, subscription or consumables&lt;/h2&gt;

&lt;p&gt;Tare has no networking code. It plays the same in airplane mode, and its App Store privacy label reads Data Not Collected. Ads would bring network code and a third-party SDK into a game built to have neither.&lt;/p&gt;

&lt;p&gt;The purchase leaves the label as it was. StoreKit is Apple’s own store, not an SDK the game reports through. The game records nothing about the purchase beyond the fact that the chapters are open, and no analytics are attached to the offer, neither when it is shown nor when it is dismissed.&lt;/p&gt;

&lt;p&gt;Subscriptions and consumables are ruled out entirely; the plan’s words are “no consumables, no subscriptions, ever”. The blueprint describes Tare as a crafted object, and it is sold like one, once. Hints cost a star. Nothing in a level can be bought, and stars and canvases can only be earned. If anything else is ever sold, the plan limits it to optional cosmetic theme packs released alongside free levels, and the canvases you earn would never be part of them.&lt;/p&gt;

&lt;h2 id=&quot;family-sharing-restoring-and-keeping-the-unlock&quot;&gt;Family Sharing, restoring, and keeping the unlock&lt;/h2&gt;

&lt;p&gt;Family Sharing is on. One purchase covers your family group, and the game treats a shared purchase exactly like your own.&lt;/p&gt;

&lt;p&gt;Restore purchases is always visible, in Settings and on the unlock screen, whether or not you’ve bought anything. On a new device you have to be able to find it before it has anything to restore.&lt;/p&gt;

&lt;p&gt;Once granted, the unlock stays. The app clears it only when the App Store reports the purchase revoked, for example after a refund, and never because the store couldn’t be reached. The design rules out locking a paying player out of an offline game to re-check a purchase.&lt;/p&gt;

&lt;p&gt;Chapters still open in order. Chapter II opens when 16 of Chapter I’s 20 levels are solved, and the unlock screen says the chapters open in order before you pay, so buying at level 3 holds no surprise. Within a chapter you can skip past up to three unsolved levels, so no single puzzle walls you off.&lt;/p&gt;

&lt;p&gt;There are no error codes. If the App Store doesn’t answer, the unlock screen shows Try again, with Restore and the terms still there, and the button on the wall stays where it was.&lt;/p&gt;

&lt;h2 id=&quot;the-purchase-app-review-couldnt-find&quot;&gt;The purchase App Review couldn’t find&lt;/h2&gt;

&lt;p&gt;The offer turned out to be too quiet. App Review answered the first 1.0 submission with Guideline 2.1(b), Information Needed: it could not locate the in-app purchase. The offer lived only on the chapter wall, below Chapter I’s twenty levels, and on the unlit levels, which by design carry no padlock and no price. Settings, where a reviewer looks for a purchase, had only Restore.&lt;/p&gt;

&lt;p&gt;So on 1 October the same Open Chapters II-IV button went into Settings, directly above Restore purchases, and the reply to App Review spelled out the path step by step. Both places use one view, so it looks and reads the same, and it disappears once you’ve bought.&lt;/p&gt;

&lt;h2 id=&quot;ratings-and-sharing&quot;&gt;Ratings and sharing&lt;/h2&gt;

&lt;p&gt;Tare asks for a rating only with Apple’s standard prompt, and only in two places: when you finish Chapter II and when you finish Chapter IV, and only if you’ve solved at least three levels in that session. That count lives in memory and is never saved. Finishing the free chapter never triggers the prompt, so it can’t appear anywhere near the purchase.&lt;/p&gt;

&lt;p&gt;Settings also has a Share Tare row. It hands the system share sheet the plain App Store link with no campaign or referrer parameter, because in the plan’s words a shared link that reports who shared it is “analytics by another name”. The &lt;a href=&quot;/apps/tare/privacy/&quot;&gt;privacy policy&lt;/a&gt; lists what stays on your device.&lt;/p&gt;

&lt;p&gt;Tare runs on iPhone and iPad with iOS or iPadOS 18 or later. The free chapter is also where the game teaches itself without a word, which &lt;a href=&quot;/journal/wordless-puzzle-game-design/&quot;&gt;designing a puzzle with no words&lt;/a&gt; walks through. To see how other models compare, &lt;a href=&quot;/guides/best-logic-puzzle-games-iphone/&quot;&gt;the best logic puzzle games for iPhone&lt;/a&gt; sets Tare beside ad-supported and pay-once games, and the comparison pages cover &lt;a href=&quot;/alternatives/good-sudoku/&quot;&gt;Good Sudoku&lt;/a&gt;, &lt;a href=&quot;/alternatives/nonograms-katana/&quot;&gt;Nonograms Katana&lt;/a&gt; and &lt;a href=&quot;/alternatives/simon-tatham-puzzles/&quot;&gt;Simon Tatham’s Puzzles&lt;/a&gt;. &lt;a href=&quot;/apps/millrace/&quot;&gt;Millrace&lt;/a&gt;, from the same studio, is a tile puzzle whose whole game is free, with no ads.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>How to solve a balance puzzle, and how Tare proves every level has one answer</title>
    <link href="https://lagerland-apps.github.io/journal/how-to-solve-balance-puzzles/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/how-to-solve-balance-puzzles/</id>
    <published>2026-10-09T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Tare&apos;s levels are hanging mobiles you balance with numbered weights, and some of the weights are hidden. Every one was built by hand, and none ships until the test suite proves three things about it: it has exactly one answer, its cards alone name every hidden weight, and its decoys fit nowhere. This post shows how to solve one, then how the proof works.</summary>
    <content type="html">&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Update, version 1.1:&lt;/strong&gt; Tare now has 200 levels in ten chapters of twenty. Chapter I is still free, and one purchase unlocks the other 180. Every one of the 200 levels has exactly one answer. This post is the launch-day record: its level numbers, tables and counts describe the 80 levels of Chapters I to IV in version 1.0.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Every level of &lt;a href=&quot;/apps/tare/&quot;&gt;Tare&lt;/a&gt; is a hanging mobile: beams on strings, hooks on the beams, and a shelf of weights numbered 1 to 9. You hang every weight so that every beam balances at once. Some hide inside a “?” bubble drawn at one fixed size, and the scale won’t tell you what they weigh; small picture cards above the board will. All 80 were built by hand, and none ships until a gate in the test suite has proved three things about it:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Exactly one arrangement balances.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The cards alone pin every hidden weight&lt;/strong&gt; to a single value.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Every decoy fits no balanced arrangement at all.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;First the method, on a real level, then the gate.&lt;/p&gt;

&lt;h2 id=&quot;the-one-rule-weight--distance&quot;&gt;The one rule: weight × distance&lt;/h2&gt;

&lt;p&gt;A beam is level when the turning force on each side of its pivot is equal. Each weight contributes its number times its distance from the pivot, counted in notches from 1 to 4. A 2 two notches out balances a 4 one notch out, because 2 × 2 = 4 × 1. Several weights on one side add up.&lt;/p&gt;

&lt;p&gt;Beams can hang from other beams. A hanging beam pulls on its hook with the total of everything below it, and the beams themselves weigh nothing. So a child beam has to balance on its own, and its parent sees only one number: its load.&lt;/p&gt;

&lt;p&gt;A level is solved when every hook holds a weight and every beam is level. Two pieces of the same weight are interchangeable, so swapping them is not a second answer.&lt;/p&gt;

&lt;h2 id=&quot;read-the-cards-before-you-hang-anything&quot;&gt;Read the cards before you hang anything&lt;/h2&gt;

&lt;p&gt;On a real scale you could weigh a secret by hanging it and watching the beam tip. Tare doesn’t allow that. A beam carrying an unsolved “?” doesn’t tilt: it sways slowly, about 3° either side of level, and never settles, and the sway climbs to every beam above it. If it tilted truthfully, you could binary-search every hidden value by reading angles, and the puzzle would become measurement.&lt;/p&gt;

&lt;p&gt;So the cards are the only scale for a secret. Each card is itself a small beam:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Card&lt;/th&gt;
      &lt;th&gt;What it shows&lt;/th&gt;
      &lt;th&gt;What it tells you&lt;/th&gt;
      &lt;th&gt;From the game&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Equal&lt;/td&gt;
      &lt;td&gt;Level, equal arms&lt;/td&gt;
      &lt;td&gt;Both sides weigh the same; two pieces on one side add up&lt;/td&gt;
      &lt;td&gt;Chapter II, level 5: “?” = 1 + 3, so 4&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Tilted&lt;/td&gt;
      &lt;td&gt;Heavy side down&lt;/td&gt;
      &lt;td&gt;That side is strictly heavier; two tilts can bracket a value&lt;/td&gt;
      &lt;td&gt;Chapter II, level 3: heavier than the 3, lighter than the 5, so 4&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Ratio&lt;/td&gt;
      &lt;td&gt;Level, unequal arms&lt;/td&gt;
      &lt;td&gt;Multiply each side by its notches&lt;/td&gt;
      &lt;td&gt;Chapter II, level 10: “?” at notch 1 balances a 4 at notch 2, so 8&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Twin rule&lt;/td&gt;
      &lt;td&gt;No card; it holds everywhere&lt;/td&gt;
      &lt;td&gt;Pieces with the same silhouette weigh the same&lt;/td&gt;
      &lt;td&gt;Solve one twin and you know both&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;A card can also show a weight that isn’t in your tray, drawn only for comparison. Chapter II’s first level sets its “?” against a 3 you don’t own.&lt;/p&gt;

&lt;h2 id=&quot;a-worked-example-chapter-ii-level-14&quot;&gt;A worked example: Chapter II, level 14&lt;/h2&gt;

&lt;p&gt;A top beam with no hooks of its own carries two beams, two notches either side of its pivot. The left beam has a hook one notch either side. The right beam has hooks two notches and one notch left, and one notch right. The tray holds a “?”, a 3, two 6s and a 7: five pieces for five hooks.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;The cards.&lt;/strong&gt; One card shows the “?” heavier than a 1. The other shows it lighter than the 3. Weights are whole numbers, so the “?” is 2.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The top beam.&lt;/strong&gt; Both children hang two notches out, so they balance only if they carry the same load. The tray totals 2 + 3 + 6 + 6 + 7 = 24, so each child carries 12.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The left beam.&lt;/strong&gt; Equal arms with one hook each means two equal weights. The only pair is the two 6s, and 6 + 6 = 12.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The right beam.&lt;/strong&gt; It gets the 2, 3 and 7, also 12. Its one right-hand hook must match both left hooks. Put the 7 there, the 2 two notches out and the 3 one notch out: 4 + 3 = 7. With the 2 or the 3 on the right, the left side comes to at least 11.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Check the top.&lt;/strong&gt; 12 × 2 on each side: 24 against 24.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;While you play it, the left beam settles level as soon as both 6s are on, because nothing on it is hidden. Once the “?” hangs on the right beam, that beam and the top beam sway until the level is solved.&lt;/p&gt;

&lt;h2 id=&quot;habits-that-solve-most-levels&quot;&gt;Habits that solve most levels&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Cards first, then arrange.&lt;/strong&gt; They are always enough to name every “?”.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Work from the bottom up.&lt;/strong&gt; A parent sees only a child’s total.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Equal distances mean equal loads.&lt;/strong&gt; Two beams hung equally far either side of a pivot carry the same total.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Count the tray.&lt;/strong&gt; Every hook takes one weight, so pieces minus hooks is the number of decoys.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;how-a-level-is-built&quot;&gt;How a level is built&lt;/h2&gt;

&lt;p&gt;These 80 are the second attempt. On 1 September I played the first two finished chapters: every level was a single flat beam, the cards were hard to read, and there was no reason to keep going. The next day the arc was redesigned so that chapters mix mechanics and the mobile changes shape from level to level.&lt;/p&gt;

&lt;p&gt;The design notes call the method “sketched by hand, proven by machine”. A level starts as a silhouette, one of ten families: bar, lever, pendant, yoke, fork, outrigger, cradle, ladder, staircase and tree. No structure appears twice in the game, and from level 6 on, no two neighbours on a chapter’s four-column grid share a family.&lt;/p&gt;

&lt;p&gt;A search in the test target then fills in the numbers. It runs combinations of weights from 1 to 9, one per hook, through the game’s own solver and keeps those with exactly one answer, every piece hung and no beam side above 36, ranked by how badly a player who never counts does or by how much work the cards have to do. A card assistant proposes cards and keeps only sets the deduction engine accepts. Then I choose by hand: nice numbers, a symmetry that misleads, a satisfying last piece.&lt;/p&gt;

&lt;p&gt;Every level stays inside the same limits: weights 1 to 9, hooks at notches 1 to 4, at most eight pieces, eight hooks, three beams deep, three hidden weights, three decoys and three cards, and 36 on any side of any beam, so the arithmetic fits in your head.&lt;/p&gt;

&lt;h2 id=&quot;what-the-gate-proves&quot;&gt;What the gate proves&lt;/h2&gt;

&lt;p&gt;As with &lt;a href=&quot;/journal/how-millrace-levels-are-made/&quot;&gt;Millrace’s levels&lt;/a&gt;, the gate is a test that runs over every bundled level, not a script run once.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exactly one arrangement.&lt;/strong&gt; The solver tries every way to fill the hooks, up to 40,320 for eight pieces on eight hooks, branching on weights instead of pieces and filling the deepest beams first so a beam that can’t balance is abandoned early. It may call a level unique only if it searched to the end. Its shortcuts are tested against a deliberately naive solver: on an eight-hook test level with 882 solutions, both find the same 882.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Every “?” from the cards alone.&lt;/strong&gt; A separate check ignores the mobile. It tries every value from 1 to 9 for each hidden weight, at most 729 combinations for three, against every card and the twin rule. Exactly one may survive, and it must be the level’s real weight. Another check confirms each card is true as drawn, using its own arithmetic and not the deduction engine’s, so a bug in one can’t hide a card that lies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Every decoy fits nowhere.&lt;/strong&gt; The pieces flagged as decoys must be exactly the pieces no balanced arrangement uses. Because the solver counts by weight, a decoy can never share a weight with a piece that hangs: there would be no fact about which of the two is spare.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No decorative cards.&lt;/strong&gt; On a level with a “?”, every card must belong to the smallest set of cards that pins down some hidden weight.&lt;/p&gt;

&lt;p&gt;Each check has a deliberately broken level in the suite that it must catch: one with two answers, one with a lying card, one whose “?” the cards leave open. A failure names the level and the rule it broke. For this post, all 80 were also re-checked by a brute-force script that shares no code with the app: 80 single answers, every “?” pinned to its real weight, every decoy unused.&lt;/p&gt;

&lt;h2 id=&quot;the-80-level-ramp&quot;&gt;The 80-level ramp&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Chapter&lt;/th&gt;
      &lt;th&gt;Levels&lt;/th&gt;
      &lt;th&gt;Hooks&lt;/th&gt;
      &lt;th&gt;Beams deep (1 / 2 / 3)&lt;/th&gt;
      &lt;th&gt;Levels with a “?”&lt;/th&gt;
      &lt;th&gt;Hidden weights (most in one level)&lt;/th&gt;
      &lt;th&gt;Decoys&lt;/th&gt;
      &lt;th&gt;Cards&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;I · The Hang (free)&lt;/td&gt;
      &lt;td&gt;1-20&lt;/td&gt;
      &lt;td&gt;2-6&lt;/td&gt;
      &lt;td&gt;10 / 7 / 3&lt;/td&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;4 (1)&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt;5&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;II · The Secret&lt;/td&gt;
      &lt;td&gt;21-40&lt;/td&gt;
      &lt;td&gt;3-6&lt;/td&gt;
      &lt;td&gt;6 / 9 / 5&lt;/td&gt;
      &lt;td&gt;20&lt;/td&gt;
      &lt;td&gt;33 (2)&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt;35&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;III · The Cascade&lt;/td&gt;
      &lt;td&gt;41-60&lt;/td&gt;
      &lt;td&gt;4-7&lt;/td&gt;
      &lt;td&gt;1 / 9 / 10&lt;/td&gt;
      &lt;td&gt;13&lt;/td&gt;
      &lt;td&gt;29 (3)&lt;/td&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;30&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;IV · The Exhibition&lt;/td&gt;
      &lt;td&gt;61-80&lt;/td&gt;
      &lt;td&gt;4-6&lt;/td&gt;
      &lt;td&gt;2 / 11 / 7&lt;/td&gt;
      &lt;td&gt;14&lt;/td&gt;
      &lt;td&gt;28 (3)&lt;/td&gt;
      &lt;td&gt;30&lt;/td&gt;
      &lt;td&gt;24&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;All&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;80&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;2-7&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;19 / 36 / 25&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;51&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;94&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;31&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;94&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Counting all 80 in order, each idea arrives on a fixed level: the first nested beam at 7, the first card at 10, the first “?” at 11, three beams deep at 15, the first sum card at 17, a weight you don’t own at 21, the first bracket at 23, the first ratio at 30, three hidden weights at 51, and one decoy at 60 as a preview of Chapter IV, where every level has one or two.&lt;/p&gt;

&lt;p&gt;The solver’s own counts show the climb. Chapter I’s first level took it 2 weight-into-hook trials; Chapter IV’s level 19 took 600. On levels with nothing hidden, a simulated player who never counts hangs everything at random, then keeps making the swap that most reduces the tilt, from 300 fixed starts. It solves the first three levels every time, Chapter I’s level 18 one time in ten, and the finale 13% of the time. Ignore the cards on Chapter IV’s level 17 and 294 combinations of hidden values and arrangements balance; with them, one does. Chapter IV’s level 11 puts exactly 36 on one side of a beam, the cap.&lt;/p&gt;

&lt;p&gt;Tare is a free download for iPhone and iPad. Chapter I’s 20 levels are free to keep, and one $2.99 purchase unlocks the other 180. There are no ads, it works offline, and its App Store privacy label reads Data Not Collected; the &lt;a href=&quot;/apps/tare/privacy/&quot;&gt;privacy policy&lt;/a&gt; has the details. How the first levels teach all of this without a word is in &lt;a href=&quot;/journal/wordless-puzzle-game-design/&quot;&gt;designing a puzzle with no words&lt;/a&gt;, and why the rest costs $2.99 once is in &lt;a href=&quot;/journal/puzzle-game-no-ads-one-purchase/&quot;&gt;no ads, no subscription&lt;/a&gt;. No level needs a guess. The cards are always enough, and the tests have checked that they are.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>Xiangqi openings explained: the Central Cannon, its answers, and the quieter first moves</title>
    <link href="https://lagerland-apps.github.io/journal/xiangqi-openings-explained/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/xiangqi-openings-explained/</id>
    <published>2026-10-07T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Xiangqi opening theory is narrower than chess theory. One first move is the most common, a handful of named answers meet it, and five quieter first moves make up the rest of the list. This post covers the ten openings worth knowing by name, the notation they are written in, and the main line of the Central Cannon against the Screen Horses, move by move.</summary>
    <content type="html">&lt;p&gt;Xiangqi openings are named after one move. If Red’s first move puts a cannon on the central file, it is a Central Cannon game, and the opening is then named after Black’s answer. If Red plays anything else, the opening is named after that move. The ten below are the names to learn first.&lt;/p&gt;

&lt;h2 id=&quot;how-to-read-the-moves&quot;&gt;How to read the moves&lt;/h2&gt;

&lt;p&gt;The moves here are in WXF notation, named after the &lt;a href=&quot;https://www.wxf-xiangqi.org/&quot;&gt;World Xiangqi Federation&lt;/a&gt;. It is a letter-and-number form of the traditional Chinese notation, and one of the two notations Xiangqiful offers.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;The letter is the piece:&lt;/strong&gt; K general, A advisor, E elephant, H horse, R chariot, C cannon, P soldier.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The first number is the column the piece starts on,&lt;/strong&gt; counted 1 to 9 from the moving player’s own right. The two players count from opposite sides, so Red’s column 2 is Black’s column 8.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The sign is the direction:&lt;/strong&gt; + forward, - backward, = sideways.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The last number&lt;/strong&gt; is the distance for a chariot, cannon, soldier or general moving forward or back. For a sideways move, and for every horse, elephant and advisor move, it is the destination column.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Two identical pieces on one column&lt;/strong&gt; are told apart by + (front) and - (rear) in place of the column number.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So C2=5 is a cannon moving sideways from column 2 to column 5, and H8+7 is a horse moving forward from column 8 to column 7. Chinese notation follows the same pattern with characters: C2=5 is 炮二平五 and Black’s H8+7 is 马8进7, with Chinese numerals for Red and Arabic numerals for Black (&lt;a href=&quot;https://en.wikipedia.org/wiki/Xiangqi&quot;&gt;Wikipedia’s xiangqi article&lt;/a&gt; describes both).&lt;/p&gt;

&lt;h2 id=&quot;the-ten-openings-at-a-glance&quot;&gt;The ten openings at a glance&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Opening&lt;/th&gt;
      &lt;th&gt;Chinese&lt;/th&gt;
      &lt;th&gt;First moves&lt;/th&gt;
      &lt;th&gt;Played by&lt;/th&gt;
      &lt;th&gt;The idea&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Central Cannon&lt;/td&gt;
      &lt;td&gt;中炮&lt;/td&gt;
      &lt;td&gt;1. C2=5&lt;/td&gt;
      &lt;td&gt;Red&lt;/td&gt;
      &lt;td&gt;Cannon on the middle file, aimed at e6 and the palace&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Screen Horses&lt;/td&gt;
      &lt;td&gt;屏风马&lt;/td&gt;
      &lt;td&gt;1. C2=5 H8+7 2. H2+3 H2+3&lt;/td&gt;
      &lt;td&gt;Black&lt;/td&gt;
      &lt;td&gt;Both horses guard the central soldier and each other&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Same Direction Cannons&lt;/td&gt;
      &lt;td&gt;顺炮&lt;/td&gt;
      &lt;td&gt;1. C2=5 C8=5&lt;/td&gt;
      &lt;td&gt;Black&lt;/td&gt;
      &lt;td&gt;A central cannon from the same wing; near-symmetry and a race to develop&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Opposite Cannons&lt;/td&gt;
      &lt;td&gt;列炮&lt;/td&gt;
      &lt;td&gt;1. C2=5 C2=5&lt;/td&gt;
      &lt;td&gt;Black&lt;/td&gt;
      &lt;td&gt;A central cannon from the other wing; sharper, counterattacking&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Reversed Palace Horses&lt;/td&gt;
      &lt;td&gt;反宫马&lt;/td&gt;
      &lt;td&gt;1. C2=5 H8+7 2. H2+3 C2=4 3. R1=2 H2+3&lt;/td&gt;
      &lt;td&gt;Black&lt;/td&gt;
      &lt;td&gt;Screen Horses with a cannon in the advisor’s corner between them&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Elephant Opening&lt;/td&gt;
      &lt;td&gt;飞相局&lt;/td&gt;
      &lt;td&gt;1. E3+5&lt;/td&gt;
      &lt;td&gt;Red&lt;/td&gt;
      &lt;td&gt;A solid first move that makes no threat and no commitment&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Immortal Points the Way&lt;/td&gt;
      &lt;td&gt;仙人指路&lt;/td&gt;
      &lt;td&gt;1. P7+1&lt;/td&gt;
      &lt;td&gt;Red&lt;/td&gt;
      &lt;td&gt;One soldier forward, keeping every plan open until Black declares&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Horse Opening&lt;/td&gt;
      &lt;td&gt;起马局&lt;/td&gt;
      &lt;td&gt;1. H2+3&lt;/td&gt;
      &lt;td&gt;Red&lt;/td&gt;
      &lt;td&gt;A horse first, keeping the cannon plans available&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Cross-Palace Cannon&lt;/td&gt;
      &lt;td&gt;过宫炮&lt;/td&gt;
      &lt;td&gt;1. C2=6&lt;/td&gt;
      &lt;td&gt;Red&lt;/td&gt;
      &lt;td&gt;The cannon crosses in front of its own palace to attack the far wing&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Advisor-Corner Cannon&lt;/td&gt;
      &lt;td&gt;士角炮&lt;/td&gt;
      &lt;td&gt;1. C2=4&lt;/td&gt;
      &lt;td&gt;Red&lt;/td&gt;
      &lt;td&gt;The cannon stops beside the advisor, flexible and unhurried&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;why-the-central-cannon-comes-first&quot;&gt;Why the Central Cannon comes first&lt;/h2&gt;

&lt;p&gt;After 1. C2=5, the cannon on e2 already has a screen: Red’s own soldier on e3. It can jump that soldier and take the black soldier on e6, so the move develops a piece and makes a threat at once. Wikipedia calls it the most common opening in the game. Black has to deal with the threat to e6 before anything else.&lt;/p&gt;

&lt;p&gt;The Screen Horses deal with it most directly. After 1… H8+7 the horse on g7 guards e6, and after the second horse reaches c7 both of them do. If the cannon takes the soldier now, a horse takes the cannon, and Red has given a cannon for a soldier. Xiangqiful’s lesson on piece values uses exactly this capture as its example of a bad trade.&lt;/p&gt;

&lt;p&gt;The other three answers fight back instead. In the Same Direction Cannons and the Opposite Cannons, Black puts a cannon on the central file too, and the difference is which wing it left behind. In the Reversed Palace Horses, Black develops one horse, puts a cannon into the advisor’s corner, and then brings the second horse out around it. The cannon’s square matters: in this move order it goes to d7, because on f7 it would block the leg the g7 horse uses to defend e6.&lt;/p&gt;

&lt;h2 id=&quot;the-main-line-move-by-move&quot;&gt;The main line, move by move&lt;/h2&gt;

&lt;p&gt;The Central Cannon against the Screen Horses:&lt;/p&gt;

&lt;p&gt;1. C2=5 H8+7 2. H2+3 R9=8 3. R1=2 H2+3 4. R2+4 P7+1 5. P5+1 E3+5 6. H8+7 A4+5&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;2. H2+3&lt;/strong&gt; backs the cannon up with a horse. The cannon cannot do the work alone.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;2… R9=8&lt;/strong&gt; and &lt;strong&gt;3. R1=2&lt;/strong&gt; bring a chariot onto the file each side’s horse has just cleared. This is the most important habit in xiangqi openings. Leaving the chariots at home is called the Delayed Chariot (缓开车): a real system when it is chosen on purpose, and the classic beginner’s mistake when it is not.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;3… H2+3&lt;/strong&gt; completes the screen. Two horses now defend e6.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;4. R2+4&lt;/strong&gt; is the Riverbank Chariot. It stops on Red’s own bank of the river, just short of crossing, where it is hard to chase away and eyes Black’s horse on the g-file.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;4… P7+1&lt;/strong&gt; pushes the soldier in front of the g7 horse, which frees the horse’s forward moves.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;5. P5+1&lt;/strong&gt; advances the central soldier to e4. It still screens the cannon, and it claims space in the centre.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;6. H8+7 A4+5&lt;/strong&gt; completes development. Both sides are fully developed and nothing has been forced.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You will reach this position again and again, and from here the game turns on who opens a file first.&lt;/p&gt;

&lt;h2 id=&quot;which-openings-to-learn-first&quot;&gt;Which openings to learn first&lt;/h2&gt;

&lt;p&gt;Learn one opening for Red and one answer to the Central Cannon for Black, and learn the plans in them before you learn them many moves deep. The Central Cannon and the Screen Horses are the natural pair because you will meet them most. Whichever you choose, the chariots decide the opening: get them out early, onto open files. Wikipedia mentions an old saying against moving a chariot in the first three moves and notes that modern play often ignores it. The main line above has both chariots moving by move three.&lt;/p&gt;

&lt;h2 id=&quot;how-xiangqiful-teaches-openings&quot;&gt;How Xiangqiful teaches openings&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/apps/xiangqiful/&quot;&gt;Xiangqiful&lt;/a&gt; teaches openings in two places.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Openings lesson track&lt;/strong&gt; has ten lessons. “Opening Principles” comes first, then the Central Cannon, the Screen Horses, the Same-Direction and Opposite Cannons, the Reversed Palace Horses, the Elephant Opening, the Immortal Points the Way and the Cross-Palace Cannon. It ends with “Choosing a Repertoire”, which makes the same case as the section above. Every line is played from the standard start and was machine-checked as legal. All 80 lessons in the app are free.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Opening Lab&lt;/strong&gt; has ten opening families with five lines each, from the first moves into the early middlegame. Most families are played as Red. The Screen Horses and Reversed Palace Horses, where the defence is the subject, are played as Black. The opponent’s replies are played for you. A wrong move does not end the line: the app says so, draws the wanted move on the board and lets you try again from the same move. Move orders that reach the same position are accepted. Some lines show the opponent’s other main reply, and one shows what the cannon on f7 costs in the Reversed Palace Horses. Every line was replayed for legality and checked by the engine. The Central Cannon family is free; the other nine families are Premium.&lt;/p&gt;

&lt;p&gt;Moves can be shown in WXF or Chinese notation, and switching relabels the games you have already played. After each game, Pikafish reviews every move on your device, and Game Review names an early slip as an opening inaccuracy. If you are still learning how the pieces move, start with &lt;a href=&quot;/journal/xiangqi-rules-for-chess-players/&quot;&gt;the xiangqi rules for chess players&lt;/a&gt;. Shogi players will notice a similar first decision in &lt;a href=&quot;/journal/shogi-openings-for-beginners/&quot;&gt;Static Rook against Ranging Rook&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Xiangqiful is free, with Premium at $1.99 a month or $9.99 a year (each with a one-week free trial) or $19.99 once. To play these openings against people, see &lt;a href=&quot;/guides/best-xiangqi-apps-iphone/&quot;&gt;the guide to xiangqi apps for iPhone&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>Xiangqi rules for chess players: what carries over, and what catches you out</title>
    <link href="https://lagerland-apps.github.io/journal/xiangqi-rules-for-chess-players/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/xiangqi-rules-for-chess-players/</id>
    <published>2026-10-04T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">If you play chess, you already know half of xiangqi. The chariot is a rook, the horse is almost a knight, and checkmate still ends the game. The other half is a short list of rules, and most of it reverses a chess habit. Here is the board, every piece next to its chess cousin, and the rules that cost chess players their first games.</summary>
    <content type="html">&lt;p&gt;A chess player who sits down at a xiangqi board recognises most of it within a minute. There are two armies, a king-like piece to trap, a rook and a knight. Only a few rules differ, but most of them reverse a chess habit, and those are the ones that cost games. Below is the full list, with the board first and the reasoning after.&lt;/p&gt;

&lt;h2 id=&quot;the-board&quot;&gt;The board&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Nine lines by ten.&lt;/strong&gt; Pieces stand on the 90 intersections, not in squares, and move along the lines.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The river&lt;/strong&gt; runs across the middle, between the fifth and sixth ranks. It stops elephants and changes how soldiers move.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The palace&lt;/strong&gt; is the three-by-three block of points at each end, marked with a diagonal cross. The general and its two advisors never leave it.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Red moves first&lt;/strong&gt;, as in most modern tournaments (&lt;a href=&quot;https://en.wikipedia.org/wiki/Xiangqi&quot;&gt;Wikipedia’s xiangqi article&lt;/a&gt; covers the history).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The start position:&lt;/strong&gt; chariot, horse, elephant, advisor, general, advisor, elephant, horse, chariot on the back line; a cannon on each side two lines in front of the horses; five soldiers on alternate points of the fourth line.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;every-piece-next-to-its-chess-cousin&quot;&gt;Every piece, next to its chess cousin&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Piece&lt;/th&gt;
      &lt;th&gt;Red / Black&lt;/th&gt;
      &lt;th&gt;WXF letter&lt;/th&gt;
      &lt;th&gt;Chess cousin&lt;/th&gt;
      &lt;th&gt;How it moves&lt;/th&gt;
      &lt;th&gt;The catch&lt;/th&gt;
      &lt;th&gt;Rough value&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;General&lt;/td&gt;
      &lt;td&gt;帥 / 將&lt;/td&gt;
      &lt;td&gt;K&lt;/td&gt;
      &lt;td&gt;King&lt;/td&gt;
      &lt;td&gt;One point orthogonally&lt;/td&gt;
      &lt;td&gt;Never leaves the palace and never moves diagonally&lt;/td&gt;
      &lt;td&gt;n/a&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Advisor&lt;/td&gt;
      &lt;td&gt;仕 / 士&lt;/td&gt;
      &lt;td&gt;A&lt;/td&gt;
      &lt;td&gt;None&lt;/td&gt;
      &lt;td&gt;One point diagonally&lt;/td&gt;
      &lt;td&gt;Never leaves the palace, so it has five points in all&lt;/td&gt;
      &lt;td&gt;2&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Elephant&lt;/td&gt;
      &lt;td&gt;相 / 象&lt;/td&gt;
      &lt;td&gt;E&lt;/td&gt;
      &lt;td&gt;Bishop, loosely&lt;/td&gt;
      &lt;td&gt;Exactly two points diagonally&lt;/td&gt;
      &lt;td&gt;Blocked if the point in between is occupied; never crosses the river&lt;/td&gt;
      &lt;td&gt;2&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Horse&lt;/td&gt;
      &lt;td&gt;傌 / 馬&lt;/td&gt;
      &lt;td&gt;H&lt;/td&gt;
      &lt;td&gt;Knight&lt;/td&gt;
      &lt;td&gt;One point straight, then one diagonally outward&lt;/td&gt;
      &lt;td&gt;Does not jump: a piece on the first point blocks it&lt;/td&gt;
      &lt;td&gt;4&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Chariot&lt;/td&gt;
      &lt;td&gt;俥 / 車&lt;/td&gt;
      &lt;td&gt;R&lt;/td&gt;
      &lt;td&gt;Rook&lt;/td&gt;
      &lt;td&gt;Any distance along a line&lt;/td&gt;
      &lt;td&gt;None. It is a rook&lt;/td&gt;
      &lt;td&gt;9&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Cannon&lt;/td&gt;
      &lt;td&gt;炮 / 砲&lt;/td&gt;
      &lt;td&gt;C&lt;/td&gt;
      &lt;td&gt;None&lt;/td&gt;
      &lt;td&gt;Like a chariot&lt;/td&gt;
      &lt;td&gt;Captures only by jumping exactly one piece&lt;/td&gt;
      &lt;td&gt;4 to 4.5&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Soldier&lt;/td&gt;
      &lt;td&gt;兵 / 卒&lt;/td&gt;
      &lt;td&gt;P&lt;/td&gt;
      &lt;td&gt;Pawn&lt;/td&gt;
      &lt;td&gt;One point forward, and captures the same way&lt;/td&gt;
      &lt;td&gt;Gains a sideways step across the river; never moves back or promotes&lt;/td&gt;
      &lt;td&gt;1, then 2&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The values are the rough table given on Wikipedia, which rates horse and cannon equal at 4. Xiangqiful’s own lesson on piece values puts the cannon at 4.5 early on. Both agree on the trend: the cannon is stronger while the board is full of screens, the horse once it empties. Sets vary in their characters, and many use 馬 and 車 for both sides.&lt;/p&gt;

&lt;h2 id=&quot;the-rules-that-cost-chess-players-games&quot;&gt;The rules that cost chess players games&lt;/h2&gt;

&lt;h3 id=&quot;stalemate-is-a-loss-not-a-draw&quot;&gt;Stalemate is a loss, not a draw&lt;/h3&gt;

&lt;p&gt;A player with no legal move loses, in check or not. The Chinese term is 困毙 (&lt;em&gt;kùnbì&lt;/em&gt;). For a chess player it is the most expensive habit to unlearn, because steering a lost position toward stalemate hands your opponent the win. It works the other way too: boxing in the enemy general without checking it is a real way to win, and a reason to keep an escape point for your own general.&lt;/p&gt;

&lt;h3 id=&quot;the-generals-may-never-face-each-other&quot;&gt;The generals may never face each other&lt;/h3&gt;

&lt;p&gt;If the two generals stand on the same file with nothing between them, the position is illegal. A move that would create it cannot be played, as if the general could fly down the file and capture. Two things follow. A piece standing between the generals is pinned to that file, whatever it is, and in the endgame your general controls its whole open file, so it can take escape points away from the enemy general from the far end of the board. Many basic mates use your own general this way.&lt;/p&gt;

&lt;h3 id=&quot;perpetual-check-loses&quot;&gt;Perpetual check loses&lt;/h3&gt;

&lt;p&gt;In chess, checking forever is how a losing player saves a draw. In xiangqi the player who repeats the position by checking on every move must deviate or lose. Official rules also forbid perpetually chasing an unprotected piece, although a chase by the general or a soldier is allowed. If both sides check perpetually, the game is drawn. The details differ between rule sets. The &lt;a href=&quot;https://www.wxf-xiangqi.org/&quot;&gt;World Xiangqi Federation&lt;/a&gt; publishes the World Xiangqi Rules used in international play, and its manual explains the repetition rules through 110 example cases. A &lt;a href=&quot;https://arxiv.org/abs/2412.17334&quot;&gt;2024 paper on implementing them in software&lt;/a&gt; used all 110 as test cases.&lt;/p&gt;

&lt;h3 id=&quot;the-cannon-needs-exactly-one-screen&quot;&gt;The cannon needs exactly one screen&lt;/h3&gt;

&lt;p&gt;The cannon moves like a chariot. To capture, it jumps exactly one piece of either colour, its screen, and takes the first enemy piece beyond. No screen means no capture, and two pieces in between means no capture either. So the cannon becomes dangerous when something steps onto its line, including your opponent’s own pieces. At the start of the game, a cannon moved to the central file already threatens the soldier on the far bank, because your own central soldier is its screen. Check every line a cannon stands on before you move a piece onto it, or off it.&lt;/p&gt;

&lt;h3 id=&quot;the-horse-can-be-blocked&quot;&gt;The horse can be blocked&lt;/h3&gt;

&lt;p&gt;The horse moves like a knight, one point straight and one diagonally outward, but it does not jump. A piece on the point next to it in the direction of travel, the “leg”, blocks both moves on that side. A horse hemmed in by its own pieces can be worth very little, and trapping an enemy horse is a standard plan.&lt;/p&gt;

&lt;h3 id=&quot;some-pieces-can-never-attack&quot;&gt;Some pieces can never attack&lt;/h3&gt;

&lt;p&gt;Advisors stay in the palace and elephants stay on their own side of the river. Neither can ever reach the enemy general. A side left with only a general, advisors and elephants cannot force a win. That is why the attacking pieces, chariots, horses, cannons and crossed soldiers, are what decide most endgames.&lt;/p&gt;

&lt;h3 id=&quot;the-rest-of-the-list&quot;&gt;The rest of the list&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;No castling.&lt;/strong&gt; The general never leaves the palace, and the palace is its castle.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;No promotion.&lt;/strong&gt; A soldier that reaches the last line can only step sideways.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;No pawn double step and no en passant.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Soldiers capture straight ahead&lt;/strong&gt;, the same way they move, and sideways too once they have crossed the river.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The general moves only orthogonally&lt;/strong&gt;, one point at a time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;how-xiangqiful-handles-the-rules&quot;&gt;How Xiangqiful handles the rules&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/apps/xiangqiful/&quot;&gt;Xiangqiful&lt;/a&gt; enforces checkmate and stalemate as wins. For repetition it uses a simplified rule. If a position occurs three times and one side gave check on every one of its moves in the cycle, that side loses. If both sides were checking, or neither was, the game is drawn. Sixty moves without a capture is also a draw. The app does not adjudicate perpetual chasing, so it is stricter than chess and simpler than a tournament arbiter.&lt;/p&gt;

&lt;p&gt;The first time stalemate or a perpetual check decides one of your games, the game-over sheet explains the rule that just applied (“In xiangqi, having no move loses” and “Checking forever loses”). Each explanation appears once, in the first game that rule decides.&lt;/p&gt;

&lt;p&gt;The Fundamentals track teaches the same list in ten lessons, among them “The Cannon and Its Screen”, “The Horse and Its Leg”, “Stalemate - the Chess Player’s Trap” and “Perpetual Check Loses”. Each one is a short explanation, a demonstration or a puzzle, and a quiz. All 80 lessons in the app are free. On the board, tapping a piece marks the points it can legally reach. Tap a cannon and the board also marks the screen it would jump over, which is the board’s answer to the question “how did that cannon reach me?”&lt;/p&gt;

&lt;p&gt;The pieces come in three sets: traditional characters, western symbols, or a hybrid with the symbol on the character, so you can learn the rules before you learn to read 傌 and 炮. After a game, Pikafish reviews every move on your device, and Game Review names mistakes in these terms, such as a screenless cannon or a trapped horse. When you are ready for xiangqi’s own puzzle form, every move must give check, and stalemate does not count as mate; &lt;a href=&quot;/journal/xiangqi-mate-problems-from-classical-manuals/&quot;&gt;the post on Xiangqiful’s 902 mate problems&lt;/a&gt; explains where they come from.&lt;/p&gt;

&lt;p&gt;Xiangqiful is free, with Premium at $1.99 a month or $9.99 a year (each with a one-week free trial) or $19.99 once. It has no online play. To play people, &lt;a href=&quot;/alternatives/pychess/&quot;&gt;PyChess&lt;/a&gt; and &lt;a href=&quot;/alternatives/xiangqi-com/&quot;&gt;Xiangqi.com&lt;/a&gt; are the usual places, and &lt;a href=&quot;/guides/best-xiangqi-apps-iphone/&quot;&gt;the guide to xiangqi apps for iPhone&lt;/a&gt; compares the rest.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>Puzzle games without ads or lives: how free games make money, and what Millrace sells instead</title>
    <link href="https://lagerland-apps.github.io/journal/puzzle-games-without-ads-or-lives/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/puzzle-games-without-ads-or-lives/</id>
    <published>2026-10-03T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Free on the App Store covers very different deals. You pay for some free puzzle games with your attention, for others with your patience or a subscription. This post explains each model, how to spot it on a product page before you install, and lists everything Millrace sells: nine optional items, none of which a level needs.</summary>
    <content type="html">&lt;p&gt;A free puzzle game still has to be paid for somehow, so before you install one it helps to know who pays, and with what. Below are the common models, what each asks of you, and where each shows up on an App Store page, followed by the complete price list for &lt;a href=&quot;/apps/millrace/&quot;&gt;Millrace&lt;/a&gt; and the reasoning behind it.&lt;/p&gt;

&lt;h2 id=&quot;how-free-puzzle-games-make-money&quot;&gt;How free puzzle games make money&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Model&lt;/th&gt;
      &lt;th&gt;How it works&lt;/th&gt;
      &lt;th&gt;What it costs you&lt;/th&gt;
      &lt;th&gt;Where to spot it before installing&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Ads between levels&lt;/td&gt;
      &lt;td&gt;A full-screen ad after a level or a failed attempt&lt;/td&gt;
      &lt;td&gt;Time, and attention between levels&lt;/td&gt;
      &lt;td&gt;App Privacy section; reviews; often a “remove ads” purchase&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Rewarded video&lt;/td&gt;
      &lt;td&gt;You choose to watch an ad for extra moves, a hint or a life&lt;/td&gt;
      &lt;td&gt;Time, at the moment you’re stuck&lt;/td&gt;
      &lt;td&gt;Reviews and screenshots&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Lives or energy&lt;/td&gt;
      &lt;td&gt;A failed or abandoned attempt costs a life; lives refill on a timer or for money&lt;/td&gt;
      &lt;td&gt;Your play is rationed by a clock&lt;/td&gt;
      &lt;td&gt;Purchases named lives, refills or coins&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Boosters and extra moves&lt;/td&gt;
      &lt;td&gt;Paid items that make a level easier&lt;/td&gt;
      &lt;td&gt;Money, level by level&lt;/td&gt;
      &lt;td&gt;Purchases named boosters, power-ups or moves&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Subscription&lt;/td&gt;
      &lt;td&gt;A recurring fee for no ads, perks or all content&lt;/td&gt;
      &lt;td&gt;Money, every period&lt;/td&gt;
      &lt;td&gt;The In-App Purchases list&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;One-time purchases&lt;/td&gt;
      &lt;td&gt;Ad removal, level packs, hint packs or cosmetics&lt;/td&gt;
      &lt;td&gt;Money, once&lt;/td&gt;
      &lt;td&gt;The In-App Purchases list&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Many games combine several of these. Lives on a timer, boosters for sale and ads for extra moves are a common bundle in level-based puzzle sagas. Paid-upfront games take the other route: you pay once on the product page and there is usually nothing else to buy. Threes is one, and its &lt;a href=&quot;/alternatives/threes/&quot;&gt;comparison page&lt;/a&gt; covers how its paid and free editions differ.&lt;/p&gt;

&lt;p&gt;Three places on an App Store page tell you most of this:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Next to the Get button. “In-App Purchases” there means something is for sale.&lt;/li&gt;
  &lt;li&gt;The In-App Purchases list, further down the page. Item names and prices give the model away: lives, refills, coins, boosters, a remove-ads item, a monthly price.&lt;/li&gt;
  &lt;li&gt;App Privacy, where the developer declares what happens to data under four headings: Data Used to Track You, Data Linked to You, Data Not Linked to You, and Data Not Collected. Tracking, in Apple’s definition, means linking data from the app with other companies’ data for targeted advertising or ad measurement, or sharing it with data brokers.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Recent reviews fill in the rest.&lt;/p&gt;

&lt;h2 id=&quot;what-millrace-sells-the-complete-list&quot;&gt;What Millrace sells: the complete list&lt;/h2&gt;

&lt;p&gt;Millrace has no ads, lives or subscription. It sells cosmetic themes, undo tokens and a tip, and this is every item:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Item&lt;/th&gt;
      &lt;th&gt;Price (US)&lt;/th&gt;
      &lt;th&gt;Kind&lt;/th&gt;
      &lt;th&gt;What you get&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Designer Pack 1&lt;/td&gt;
      &lt;td&gt;$1.99&lt;/td&gt;
      &lt;td&gt;One-time&lt;/td&gt;
      &lt;td&gt;Studio Clay, Paper &amp;amp; Ink, Sakura Pastel, Amber, Heartwood&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Designer Pack 2&lt;/td&gt;
      &lt;td&gt;$1.99&lt;/td&gt;
      &lt;td&gt;One-time&lt;/td&gt;
      &lt;td&gt;Concrete Studio, Sunset Dunes, Glacier Ice, Brushed Metal, Midnight Neon&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Summer Pack&lt;/td&gt;
      &lt;td&gt;$1.99&lt;/td&gt;
      &lt;td&gt;One-time&lt;/td&gt;
      &lt;td&gt;Lido, Riviera, Agrumi&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Winter Pack&lt;/td&gt;
      &lt;td&gt;$1.99&lt;/td&gt;
      &lt;td&gt;One-time&lt;/td&gt;
      &lt;td&gt;Hygge Hearth, Aurora Drift, Evergreen Noël&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Complete Collection&lt;/td&gt;
      &lt;td&gt;$5.99&lt;/td&gt;
      &lt;td&gt;One-time&lt;/td&gt;
      &lt;td&gt;All sixteen paid themes&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;10 Undos&lt;/td&gt;
      &lt;td&gt;$0.99&lt;/td&gt;
      &lt;td&gt;Consumable&lt;/td&gt;
      &lt;td&gt;Undo tokens for Freeplay&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;50 Undos&lt;/td&gt;
      &lt;td&gt;$2.99&lt;/td&gt;
      &lt;td&gt;Consumable&lt;/td&gt;
      &lt;td&gt;Undo tokens for Freeplay&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;200 Undos&lt;/td&gt;
      &lt;td&gt;$5.99&lt;/td&gt;
      &lt;td&gt;Consumable&lt;/td&gt;
      &lt;td&gt;Undo tokens for Freeplay&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Support the Developer&lt;/td&gt;
      &lt;td&gt;$1.99&lt;/td&gt;
      &lt;td&gt;Tip&lt;/td&gt;
      &lt;td&gt;A “Thank you.” and nothing else&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The Complete Collection costs less than buying the four packs separately. Theme purchases restore with your Apple Account. There is no subscription. Apple derives the prices for other storefronts and shows your local currency at checkout.&lt;/p&gt;

&lt;p&gt;Free: all 64 campaign levels, Freeplay, the daily board, Hint, the Coach, Game Center and the Classic theme, which is one of seventeen. You can preview a paid theme on your own board for five moves before you decide.&lt;/p&gt;

&lt;h2 id=&quot;where-undo-tokens-fit-and-where-they-dont&quot;&gt;Where undo tokens fit, and where they don’t&lt;/h2&gt;

&lt;p&gt;Undo tokens are the one thing Millrace sells that touches play, and the closest thing it has to a booster, so their exact rules are worth setting out.&lt;/p&gt;

&lt;p&gt;Inside a level, Undo is free and unlimited and never touches your tokens. After a failed run, the card’s main button is “Undo that move”, and restarting a level costs nothing either.&lt;/p&gt;

&lt;p&gt;Tokens are spent only in Freeplay, the endless board, where tiles spawn at random. By default the app asks before it spends one.&lt;/p&gt;

&lt;p&gt;Free tokens arrive on their own: one each day while you hold fewer than three. Opening the app on consecutive days builds a streak, and the milestones at 3, 7, 14 and 30 days pay out 2, 5, 10 and 20 tokens, once each.&lt;/p&gt;

&lt;p&gt;Running out interrupts nothing. Tapping Undo with no tokens opens a sheet with the three bundles and a “Not now” button, and the game carries on either way.&lt;/p&gt;

&lt;p&gt;Hint is never rationed or sold. In a level it comes from the same solver that verified the level, as the first move of a shortest line from where you stand. &lt;a href=&quot;/journal/how-to-plan-moves-ahead-in-tile-puzzles/&quot;&gt;The strategy guide&lt;/a&gt; covers how to use it, and how to need it less.&lt;/p&gt;

&lt;h2 id=&quot;why-there-are-no-lives-or-ads&quot;&gt;Why there are no lives or ads&lt;/h2&gt;

&lt;p&gt;The project’s planning document set three rules for how the game earns its keep: never gate the base game, never make undo mandatory, and no paywalls mid-run. Everything in the price list follows from them.&lt;/p&gt;

&lt;p&gt;Lives would break the first rule most directly. A lives system makes failure cost time: you lose, and then you wait or pay. In Millrace a loss costs one tap on Undo. The comment above that button in the source says the point of a fail state “is that it costs you a thought, not a run.” The levels are hard on purpose, as &lt;a href=&quot;/journal/how-millrace-levels-are-made/&quot;&gt;how they’re made&lt;/a&gt; explains, and a hard level with a lives meter attached rewards waiting over thinking.&lt;/p&gt;

&lt;p&gt;Free Undo needed one guard. When a run fails, the card can say which move made the position unwinnable, but only afterwards and never live. A live warning plus free Undo would turn every level into swipe, undo, swipe until something sticks, and you’d reach the answer without understanding it.&lt;/p&gt;

&lt;p&gt;Ads were first ruled out as a design choice, and now the code makes them impossible. An ad has to come from somewhere, and Millrace contains no networking code; it never uploads or downloads anything itself. It links no third-party SDKs, there is no account, and Apple’s privacy label for the app reads Data Not Collected. Game Center and purchases talk to Apple, and nothing else in the app connects anywhere. The &lt;a href=&quot;/apps/millrace/privacy/&quot;&gt;privacy policy&lt;/a&gt; has the details.&lt;/p&gt;

&lt;h2 id=&quot;what-this-model-gives-up&quot;&gt;What this model gives up&lt;/h2&gt;

&lt;p&gt;A game that sells only optional items depends on some players choosing to buy something they don’t need. The design has other limits too. There are 64 levels, not thousands, and each one was generated, solved exhaustively and screened before it shipped. Progress stays on the device and doesn’t sync. If you want a long saga with events, the &lt;a href=&quot;/alternatives/two-dots/&quot;&gt;Two Dots comparison&lt;/a&gt; is fair about where Two Dots does better, and about how its lives work.&lt;/p&gt;

&lt;h2 id=&quot;a-checklist-for-any-free-puzzle-game&quot;&gt;A checklist for any free puzzle game&lt;/h2&gt;

&lt;p&gt;Before installing, five questions answer most of it:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Does failing cost anything: a life, energy, or time spent waiting?&lt;/li&gt;
  &lt;li&gt;Can every level be finished without buying anything?&lt;/li&gt;
  &lt;li&gt;Are hints and undos rationed, and are they sold?&lt;/li&gt;
  &lt;li&gt;What does the In-App Purchases list contain?&lt;/li&gt;
  &lt;li&gt;What does the App Privacy section declare?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For Millrace, failing costs nothing and every level can be finished free. Hints are never rationed, undos are free inside levels, and tokens are sold only for Freeplay. The list holds themes, undo bundles and a tip, and the label reads Data Not Collected. The &lt;a href=&quot;/apps/millrace/&quot;&gt;app page&lt;/a&gt; has the rest.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>902 xiangqi mate problems, eight old books, and the problems I left out</title>
    <link href="https://lagerland-apps.github.io/journal/xiangqi-mate-problems-from-classical-manuals/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/xiangqi-mate-problems-from-classical-manuals/</id>
    <published>2026-10-01T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Xiangqiful ships 902 consecutive-check mate problems. I composed 194 of them; the other 708 come from eight classical manuals, one of them from 1570. No book problem was edited to make it work, and the ones that didn&apos;t work aren&apos;t in the app. Below is the full count, by book and by depth, and how every line was checked.</summary>
    <content type="html">&lt;p&gt;Xiangqiful has 902 mate problems, and every one is a consecutive-check mate (连将杀). Red must check on every move until the black general is mated, and Black always picks the reply that lasts longest. I composed 194. The other 708 come from eight classical manuals, transcribed position by position and line by line. Each book line was then proved by the app’s own solver. None was edited to pass, and a book problem that failed is not in the app.&lt;/p&gt;

&lt;p&gt;The whole corpus, by source and by depth:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Source&lt;/th&gt;
      &lt;th&gt;Mate in 1&lt;/th&gt;
      &lt;th&gt;Mate in 3&lt;/th&gt;
      &lt;th&gt;Mate in 5&lt;/th&gt;
      &lt;th&gt;Mate in 7&lt;/th&gt;
      &lt;th&gt;Total&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Shiqing Yaqu (适情雅趣, 1570)&lt;/td&gt;
      &lt;td&gt;50&lt;/td&gt;
      &lt;td&gt;35&lt;/td&gt;
      &lt;td&gt;36&lt;/td&gt;
      &lt;td&gt;106&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;227&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Lanke Shenji (烂柯神机)&lt;/td&gt;
      &lt;td&gt;39&lt;/td&gt;
      &lt;td&gt;34&lt;/td&gt;
      &lt;td&gt;16&lt;/td&gt;
      &lt;td&gt;77&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;166&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Taolue Yuanji (韬略元机)&lt;/td&gt;
      &lt;td&gt;30&lt;/td&gt;
      &lt;td&gt;19&lt;/td&gt;
      &lt;td&gt;29&lt;/td&gt;
      &lt;td&gt;51&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;129&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Mengru Shenji (梦入神机)&lt;/td&gt;
      &lt;td&gt;21&lt;/td&gt;
      &lt;td&gt;15&lt;/td&gt;
      &lt;td&gt;15&lt;/td&gt;
      &lt;td&gt;43&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;94&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Yuanshen Haige (渊深海阁)&lt;/td&gt;
      &lt;td&gt;22&lt;/td&gt;
      &lt;td&gt;19&lt;/td&gt;
      &lt;td&gt;29&lt;/td&gt;
      &lt;td&gt;14&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;84&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Juzhongmi (橘中秘)&lt;/td&gt;
      &lt;td&gt;2&lt;/td&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt;2&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Zhuxiang Zhai (竹香斋)&lt;/td&gt;
      &lt;td&gt;2&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;2&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Xinwu Canbian (心武残编)&lt;/td&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Composed for Xiangqiful&lt;/td&gt;
      &lt;td&gt;78&lt;/td&gt;
      &lt;td&gt;116&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;194&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;245&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;239&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;125&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;293&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;902&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;How much of each book made it in:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Manual&lt;/th&gt;
      &lt;th&gt;Positions transcribed&lt;/th&gt;
      &lt;th&gt;Scored by the book as a Red win&lt;/th&gt;
      &lt;th&gt;In the app&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Shiqing Yaqu&lt;/td&gt;
      &lt;td&gt;549&lt;/td&gt;
      &lt;td&gt;452&lt;/td&gt;
      &lt;td&gt;227&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Lanke Shenji&lt;/td&gt;
      &lt;td&gt;258&lt;/td&gt;
      &lt;td&gt;220&lt;/td&gt;
      &lt;td&gt;166&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Taolue Yuanji&lt;/td&gt;
      &lt;td&gt;341&lt;/td&gt;
      &lt;td&gt;225&lt;/td&gt;
      &lt;td&gt;129&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Mengru Shenji&lt;/td&gt;
      &lt;td&gt;150&lt;/td&gt;
      &lt;td&gt;134&lt;/td&gt;
      &lt;td&gt;94&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Yuanshen Haige&lt;/td&gt;
      &lt;td&gt;374&lt;/td&gt;
      &lt;td&gt;115&lt;/td&gt;
      &lt;td&gt;84&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Juzhongmi&lt;/td&gt;
      &lt;td&gt;181&lt;/td&gt;
      &lt;td&gt;42&lt;/td&gt;
      &lt;td&gt;5&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Zhuxiang Zhai&lt;/td&gt;
      &lt;td&gt;200&lt;/td&gt;
      &lt;td&gt;25&lt;/td&gt;
      &lt;td&gt;2&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Xinwu Canbian&lt;/td&gt;
      &lt;td&gt;155&lt;/td&gt;
      &lt;td&gt;5&lt;/td&gt;
      &lt;td&gt;1&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;All eight&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;2,208&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;1,218&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;708&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Depth is counted in plies, single moves by either side. Mate in 3 means Red, Black, Red. That is how the app labels its tiers, and it is how tsume problems are counted in shogi. A chess book would call the same problem mate in 2.&lt;/p&gt;

&lt;h2 id=&quot;what-the-genre-demands&quot;&gt;What the genre demands&lt;/h2&gt;

&lt;p&gt;Xiangqi’s native puzzle has the same constraint as tsume-shogi. That is why the solver in &lt;a href=&quot;/apps/xiangqiful/&quot;&gt;Xiangqiful&lt;/a&gt; started as a port of the one in &lt;a href=&quot;/apps/shogiful/&quot;&gt;Shogiful&lt;/a&gt;. It has two rules. Every attacker move must give check. The defender plays the longest defence, so the line a problem records is the one that survives longest, even when a shorter one turns up first.&lt;/p&gt;

&lt;p&gt;Xiangqi adds a trap that shogi doesn’t have. A player with no legal move loses, so a quiet final move that leaves the general stranded wins a real game, but it is not a consecutive-check mate. The solver checks that the defender is in check before it counts his replies, and it only accepts a line that ends in checkmate. A straight port of the shogi solver would get this wrong, and it is the first thing the comments in that file warn about. Stalemate as a loss is one of several xiangqi rules that reverse a chess habit; &lt;a href=&quot;/journal/xiangqi-rules-for-chess-players/&quot;&gt;the rules guide for chess players&lt;/a&gt; covers the rest.&lt;/p&gt;

&lt;h2 id=&quot;152-problems-was-not-enough&quot;&gt;152 problems was not enough&lt;/h2&gt;

&lt;p&gt;The app was first going to ship only problems I composed. By early September there were 152 of them: 60 mate-in-1 and 92 mate-in-3. The mate-in-5 and mate-in-7 shards existed in the code but were empty. A Premium player on the long daily session would have seen every unseen problem in 19 days and then started getting repeats. Shogiful had already taught me what that costs. A one-star review there said that with only a few hundred problems, you end up memorising them.&lt;/p&gt;

&lt;p&gt;Composing more only went so far. The composer is a generator, and a candidate survives only if it passes a strict bar. Red must have at least two checking moves, and exactly one of them forces mate. Every red piece except the general has to be load-bearing, so removing any one of them destroys the problem. The defender must keep pieces near his general and at least six legal replies. No two problems may share a position or its mirror image. One more run per shard brought the originals to their final 194. The generator only composes mate in 1 and mate in 3, so it could never fill the two empty shards. The deep problems already existed, in books.&lt;/p&gt;

&lt;h2 id=&quot;eight-books-2208-positions&quot;&gt;Eight books, 2,208 positions&lt;/h2&gt;

&lt;p&gt;I transcribed eight pre-1900, public-domain manuals from the digital editions on xqdao.com. Each problem became a starting position and the book’s main line, in the notation the app’s rules engine reads. That came to 2,208 positions. 837 of them are draws by the book’s own verdict, 66 are wins for Black, and 87 carry no verdict at all. That left 1,218 the books score as wins for Red.&lt;/p&gt;

&lt;p&gt;Most of those don’t fit a mate-in-7 ceiling. The median main line among the 1,218 is 13 plies, the longest is 74, and only 195 are seven plies or shorter. So the import works from the end of the line. For each book problem it tries the whole problem first, then the position the book’s line reaches 7 plies before the mate, then 5, 3 and 1. It keeps the longest version that passes, and it never keeps more than one per book problem.&lt;/p&gt;

&lt;p&gt;That is why the data carries two kinds of book credit. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;classical:&lt;/code&gt; marks a whole problem, the book’s own diagram and main line, unchanged. Only 36 problems are used whole. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;after:&lt;/code&gt; marks an ending, and 672 problems are endings. For example, the Shiqing Yaqu’s first problem has an 11-ply main line. Xiangqiful’s first mate-in-7 starts from the position after the book’s fourth ply and plays the book’s last seven moves exactly. The other 194 problems are credited &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;original&lt;/code&gt;, and none of them is attributed to any collection.&lt;/p&gt;

&lt;h2 id=&quot;the-book-was-not-corrected-to-make-a-problem-fit&quot;&gt;The book was not corrected to make a problem fit&lt;/h2&gt;

&lt;p&gt;That sentence is in the provenance field of every shard file, and the import works by it. A book position and line ship only if all of these hold:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;The book claims a win for Red.&lt;/strong&gt; Draws and Black wins are never imported.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Every piece stands where a game could have put it,&lt;/strong&gt; neither side starts in check, and the line replays legally.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The book’s key move holds against every reply.&lt;/strong&gt; Books record one defence, and the solver plays out every reply the book leaves out. If any reply escapes, the problem is out.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;MateValidator accepts the book’s line at the book’s depth.&lt;/strong&gt; Every attacker move checks, the line ends in checkmate, no shorter mate exists, and exactly one first move wins.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;No later move has a twin.&lt;/strong&gt; At every Red move along the book’s line, and along every defence the solver added, the recorded move must be the only one that still mates in time. During a problem the app accepts only the recorded move, so a second mate would mark a player’s correct answer as wrong.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;It isn’t already in the corpus,&lt;/strong&gt; in either mirror image.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;A slow phone can re-prove it.&lt;/strong&gt; The solver’s work is capped at 8,000 search nodes, which keeps each problem inside the device’s two-second budget.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is no step where a failing line gets patched. The import doesn’t swap in a better key move or move a piece to remove a dual. When a book problem fails, the importer moves on to a shorter ending of the same problem. If no ending passes, the problem doesn’t ship. 708 of the 1,218 Red wins produced a problem; the other 510 produced nothing the app would ship. Not all 510 are broken, since the same gate also turns away sound problems, such as one a phone would take too long to re-prove, or one already in the corpus as a mirror image. The counts above are the real yield either way.&lt;/p&gt;

&lt;p&gt;The Juzhongmi line in the table shows the effect. Of its 181 transcribed positions, the book scores only 42 as Red wins, and five survived. The manual is still in the app: the advanced lesson track teaches from it, alongside the Plum Blossom manual (梅花谱) and the Seven Stars endgame (七星聚会).&lt;/p&gt;

&lt;h2 id=&quot;checked-twice-by-the-same-code&quot;&gt;Checked twice, by the same code&lt;/h2&gt;

&lt;p&gt;MateValidator runs twice: once when a problem is written into the bundle, and again on your device the first time the problems are loaded, before any problem reaches the puzzle database. Both runs use the same Swift source: the authoring tool compiles &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MateValidator&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MateSolver&lt;/code&gt; directly, so the gate that admitted a problem and the gate that loads it can’t drift apart.&lt;/p&gt;

&lt;p&gt;The second pass is there because a change to the rules engine can break a problem that used to be sound without anyone noticing. If that happens, a player should get a smaller corpus and never a board they can’t solve. A rejected problem never reaches the database. If an entire shard fails, the loader treats that as a shipping error and stores none of it. Mate-in-1 and mate-in-3 problems are checked during launch, and the deeper two shards in the background. Each problem gets two seconds.&lt;/p&gt;

&lt;p&gt;When the validator later gained the twin check along every line, I re-ran all 902 shipped problems through it. None was rejected, and the run took about 1.7 seconds in an optimised build. The test suite proves the whole bundled set again on every run. It’s the same idea as &lt;a href=&quot;/journal/how-millrace-levels-are-made/&quot;&gt;proving Millrace’s levels in the test suite&lt;/a&gt;: a problem that stops passing should fail by name before it can reach a player.&lt;/p&gt;

&lt;h2 id=&quot;how-the-problems-reach-you&quot;&gt;How the problems reach you&lt;/h2&gt;

&lt;p&gt;The problems live in &lt;strong&gt;Mate Trail&lt;/strong&gt;, one of Xiangqiful’s nine drill modules. The hub lists one row per depth, mate in 1, 3, 5 and 7, with how many you’ve solved in each. A session opens with “Find the mate. Every move must give check.” You play Red’s moves and the app answers with Black’s. Black’s replies come from the problem’s recorded lines, so the board never stops responding partway through.&lt;/p&gt;

&lt;p&gt;Problems you miss come back through spaced repetition. The session header marks a returning problem as a review due today, or, once the unseen ones run out, as seen before with no new problems left. There’s no credit line under the board; the source lives on every problem in the data instead.&lt;/p&gt;

&lt;p&gt;The first problem a new player sees comes from the books. During setup, before any trial offer, the app asks you to solve the last move of Lanke Shenji #46, a chariot mate with seven pieces on the board.&lt;/p&gt;

&lt;p&gt;Mate Trail is separate from the exercises Xiangqiful cuts from your own analysed games. Nobody has screened those positions for a second mate. So when the answer to one of them is a mate in one, the app accepts any mating move, not only the one it recorded.&lt;/p&gt;

&lt;p&gt;The free tier includes three training puzzles a day, and mate problems count toward that. Premium removes the limit for $1.99 a month or $9.99 a year, each with a one-week free trial, or $19.99 once. Everything runs on your device on iPhone, iPad and Mac, with no account. The &lt;a href=&quot;/apps/xiangqiful/&quot;&gt;app page&lt;/a&gt; has the rest: ten opponents, Pikafish analysis, 80 lessons and more than 150 drills. A Shiqing Yaqu problem from 1570 is in the app only because a solver confirmed what the book says.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>How to plan moves ahead in a tile puzzle: six checks, and Millrace&apos;s Level 1 move by move</title>
    <link href="https://lagerland-apps.github.io/journal/how-to-plan-moves-ahead-in-tile-puzzles/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/how-to-plan-moves-ahead-in-tile-puzzles/</id>
    <published>2026-09-27T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Nothing in a Millrace level is random, so every level can be planned to the end before your first swipe. In practice, planning is a short list of checks you run before each move. This post gives the six that matter, why each follows from the rules, and Level 1 played move by move, including the two swipes that lose it on the spot.</summary>
    <content type="html">&lt;p&gt;&lt;a href=&quot;/apps/millrace/&quot;&gt;Millrace&lt;/a&gt; is a tile-delivery puzzle: build one exact value on one marked cell inside a move budget, while tiles keep arriving through a single inlet on the board’s edge. The board is fixed and every arriving tile is shown before your first move, so a level can be planned to the end. The campaign screen states the core rule in one line: “Tiles keep arriving at the marked cell. Block it and you lose.”&lt;/p&gt;

&lt;h2 id=&quot;the-rules-that-matter-for-planning&quot;&gt;The rules that matter for planning&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Rule&lt;/th&gt;
      &lt;th&gt;What it means when you plan&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;The board is 4×4. A swipe slides every tile; two equal tiles merge into their sum, once per move.&lt;/td&gt;
      &lt;td&gt;One swipe changes all four rows or columns at once.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Tiles arrive through one inlet, on an edge, never in a corner.&lt;/td&gt;
      &lt;td&gt;Every arrival lands on the same cell.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;After each move, the next tile in the queue lands on the inlet. Only 2s and 4s arrive, and the whole queue is shown.&lt;/td&gt;
      &lt;td&gt;You know every future arrival before you start.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;If the inlet is occupied when a tile is due, the run ends: Blocked.&lt;/td&gt;
      &lt;td&gt;While tiles remain, the inlet must be empty after every move.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;The goal is one exact value on one marked cell, the vault.&lt;/td&gt;
      &lt;td&gt;Too small isn’t finished, and merging past it (a 32 when the level asks for 16) destroys it.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;The goal is checked before the next tile arrives.&lt;/td&gt;
      &lt;td&gt;The winning move can’t be spoiled by the inlet.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;The move budget is two above the shortest solution on 56 levels, one above on 6, and equal to it on 2.&lt;/td&gt;
      &lt;td&gt;At most two spare moves; on Levels 51 and 64, none.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Every legal first move leaves the level winnable.&lt;/td&gt;
      &lt;td&gt;Your first swipe can never lose.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;six-checks-before-every-swipe&quot;&gt;Six checks before every swipe&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Read the chapter as a number.&lt;/strong&gt; Each chapter is pinned to one solution length. Every Warm-up level’s shortest solution is exactly 5 moves, Tactics 6, Pressure 7, Precision 8 and Deep Water 9; Mastery runs from 10 to 16. Compare it with the “moves left” counter before your first swipe: a Tactics level that opens with 8 moves left gives you two spare moves.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Do the target arithmetic.&lt;/strong&gt; Every tile is a power of two, so the target is built from pairs: a 32 is two 16s, a 16 is two 8s. Before moving, find the tiles that will become the target, including any still in the queue. Note anything that could merge with the finished value, too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Never slide toward the inlet’s edge while a tile is due.&lt;/strong&gt; After every arrival, the newest tile sits on the inlet, against the edge. A slide toward that edge can’t move it off. It either stays put or absorbs an equal tile behind it, and either way the cell is still occupied when the next tile comes. So from move 2 on, while the queue isn’t empty, that swipe does nothing, loses, or wins. It can win because the goal is checked before the next arrival, so a slide that completes the delivery still counts. No level is an exception.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Check the inlet’s own line on the other slides.&lt;/strong&gt; Say the inlet is on the left edge. Left is check 3. Right moves the newest tile away, unless its row is still full after merging. Up and Down pack the inlet’s column toward one end, and if it holds enough tiles after merging to reach the inlet, one of them lands on it. Count before you swipe.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Count the queue.&lt;/strong&gt; Each level card shows how many tiles are arriving, and the status bar under the board shows the remaining queue with the next tile highlighted. One tile arrives after each move until the queue is empty. Level 1 has three arrivals and a 7-move budget, so the inlet matters for the first three moves only. After that, the board is a pure delivery problem. In 9 of the 64 levels the queue holds at least as many tiles as the budget has moves, so the inlet never stops mattering.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Choose your finish early.&lt;/strong&gt; A delivery ends in one of two ways. Either you build the value elsewhere and slide it onto the vault, or the final merge happens on the vault itself. In 22 levels every shortest solution ends with a slide, in 29 with a merge on the vault, and 13 can be finished either way. Carrying needs an open lane to the vault; merging there needs the second tile to line up with it. The early moves build one or the other.&lt;/p&gt;

&lt;h2 id=&quot;level-1-move-by-move&quot;&gt;Level 1, move by move&lt;/h2&gt;

&lt;p&gt;Here is the first Warm-up level’s starting board:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; &lt;/th&gt;
      &lt;th&gt;Column 1&lt;/th&gt;
      &lt;th&gt;Column 2&lt;/th&gt;
      &lt;th&gt;Column 3&lt;/th&gt;
      &lt;th&gt;Column 4&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Row 1&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;·&lt;/td&gt;
      &lt;td&gt;2&lt;/td&gt;
      &lt;td&gt;·&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Row 2&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;inlet&lt;/td&gt;
      &lt;td&gt;·&lt;/td&gt;
      &lt;td&gt;·&lt;/td&gt;
      &lt;td&gt;·&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Row 3&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;vault&lt;/td&gt;
      &lt;td&gt;·&lt;/td&gt;
      &lt;td&gt;·&lt;/td&gt;
      &lt;td&gt;·&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Row 4&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;·&lt;/td&gt;
      &lt;td&gt;·&lt;/td&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;8&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The inlet is on the left edge, second row; the vault is directly below it. The target is exactly 16. The queue is 2, 2, 2, and the budget is 7 moves. The shortest solution is 5 moves, and only one five-move line exists.&lt;/p&gt;

&lt;p&gt;Start with the arithmetic. 16 is 8 + 8, and the second 8 can come from the two 4s. The three queued 2s play no part in the target. They are the cost of the level: three tiles to keep off the inlet.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Move&lt;/th&gt;
      &lt;th&gt;Swipe&lt;/th&gt;
      &lt;th&gt;What happens&lt;/th&gt;
      &lt;th&gt;Tiles still due&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;Down&lt;/td&gt;
      &lt;td&gt;The top-left 4 drops to the bottom-left corner; the 2 in the third column stops on the 4 below it. Bottom row: 4 · 4 8. A 2 arrives on the inlet.&lt;/td&gt;
      &lt;td&gt;2&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2&lt;/td&gt;
      &lt;td&gt;Right&lt;/td&gt;
      &lt;td&gt;The bottom 4s merge: · · 8 8. The new 2 slides off the inlet to the right edge. Another 2 arrives.&lt;/td&gt;
      &lt;td&gt;1&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;Right&lt;/td&gt;
      &lt;td&gt;The 8s merge into the 16 in the bottom-right corner; the two 2s in the inlet’s row merge into a 4. The last 2 arrives.&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;Up&lt;/td&gt;
      &lt;td&gt;Nothing else is coming, so the inlet no longer matters. The right column rises, lifting the 16 into the vault’s row.&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;5&lt;/td&gt;
      &lt;td&gt;Left&lt;/td&gt;
      &lt;td&gt;The 16 slides along the third row onto the vault. Solved.&lt;/td&gt;
      &lt;td&gt;none&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The 16 is built in the far corner, away from the arrivals, and carried to the vault only after the queue is empty. That is check 5 and check 6 working together.&lt;/p&gt;

&lt;p&gt;Where it goes wrong:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Move 2, Left or Up: Blocked.&lt;/strong&gt; Two of the four swipes lose on the spot. Left pushes the 2 that just arrived against the edge (check 3). Up packs the left column, the 2 on the inlet and the 4 in the corner, into the top two cells, which puts the 4 on the inlet (check 4).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Move 3, Up: lost, quietly.&lt;/strong&gt; Up is legal and blocks nothing. It splits the two 8s: one goes to the top of the third column, the other to the second row of the fourth. With four moves left, no line brings a 16 to the vault. Nothing on screen says so, but if the run ends in a loss, the card reads “Position lost at move 3”.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Move 3, Down: safe, but slower.&lt;/strong&gt; It still wins, in six moves instead of five, so it costs one of the two spare moves.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;level-8-when-the-queue-never-runs-out&quot;&gt;Level 8: when the queue never runs out&lt;/h2&gt;

&lt;p&gt;Level 8, in Tactics, turns check 5 around. Nine tiles are queued against an 8-move budget, so a tile is due after every move the level allows. The inlet is in the top row, second column, and the vault sits right next to it in the third column. The target is exactly 32.&lt;/p&gt;

&lt;p&gt;The only shortest line takes six moves: Right, Down, Left, Down, Right, Up. Its last swipe goes toward the inlet’s own edge with four tiles still waiting. That’s the exception in check 3. Up carries a 32 from the third row onto the vault, and the goal is checked before the next tile is due. The same swipe one move earlier would have lost on the spot.&lt;/p&gt;

&lt;h2 id=&quot;why-the-checks-are-not-enough-on-their-own&quot;&gt;Why the checks are not enough on their own&lt;/h2&gt;

&lt;p&gt;Every check above looks one move ahead, and one-move play is what the levels are built to beat. Before a level ships, 280 strategies that never look past the current move play it, among them 24 versions of “keep the inlet clear”, 24 that refuse any move that loses at once, and 24 that steer the target toward the vault. If any of them wins, the level is thrown away; &lt;a href=&quot;/journal/how-millrace-levels-are-made/&quot;&gt;how Millrace’s levels are made&lt;/a&gt; covers the full battery. The checks keep you alive. Solving takes the next step: where the tile after next will land, and what the board must look like when it does.&lt;/p&gt;

&lt;h2 id=&quot;when-you-get-stuck&quot;&gt;When you get stuck&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Hint&lt;/strong&gt; draws the first move of a shortest line from where you stand, with a one-line reason. It runs the same solver that verified the level, and it’s free and unlimited.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Undo&lt;/strong&gt; inside a level is free and unlimited. After a loss, the card’s main button is “Undo that move”, not Restart. Undo tokens apply only to Freeplay, the endless board.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The result card&lt;/strong&gt; says “Best possible is N moves” when you solved a level in more moves than it needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Millrace is free on iPhone and iPad, with no ads and no lives; the &lt;a href=&quot;/apps/millrace/&quot;&gt;app page&lt;/a&gt; has the full rules. The comparisons with &lt;a href=&quot;/alternatives/threes/&quot;&gt;Threes&lt;/a&gt;, &lt;a href=&quot;/alternatives/kami-2/&quot;&gt;KAMI 2&lt;/a&gt; and &lt;a href=&quot;/alternatives/flow-free/&quot;&gt;Flow Free&lt;/a&gt; set out what each of those games asks of you.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>Sixty-four levels, none written by hand: how Millrace finds and proves its puzzles</title>
    <link href="https://lagerland-apps.github.io/journal/how-millrace-levels-are-made/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/how-millrace-levels-are-made/</id>
    <published>2026-09-24T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">I didn&apos;t write any of Millrace&apos;s 64 levels. A generator proposed them, an exhaustive solver measured each one, and a gate in the test suite threw away all but a few candidates in every thousand. This is how that works, and what an earlier version of this game&apos;s puzzle mode taught me about why it has to.</summary>
    <content type="html">&lt;p&gt;A puzzle level is real when thinking is the only way through it. Checked by machine, that idea turns into a list of testable properties. Every one of the 64 levels in &lt;a href=&quot;/apps/millrace/&quot;&gt;Millrace&lt;/a&gt;, a tile-delivery puzzle, was found by search, and none ships unless all five of these hold:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;It is solvable within its move budget.&lt;/li&gt;
  &lt;li&gt;Its shortest solution is known exactly. A breadth-first search walks the level’s entire state graph, and the first win it reaches is provably the minimum. The game calls that number the best possible; my own estimate plays no part.&lt;/li&gt;
  &lt;li&gt;No thoughtless strategy wins it. 280 strategies that never look beyond the move in front of them play it through. If one wins, the level is gone.&lt;/li&gt;
  &lt;li&gt;Random play almost never wins. The exact odds are computed (no sampling), and above 2% the level is gone.&lt;/li&gt;
  &lt;li&gt;It is not another level in disguise, whether rotated, reflected or with its tile values relabelled.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Those five head a list of sixteen numbered checks. The others keep levels fair: move one can never lose, some later line always can, a blocked inlet must be a reachable loss, the budget allows at most two spare moves, and there must be at least ten winning lines. So there are many routes through each level, and none of them is a dumb one. The chapters make one check visible:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Chapter&lt;/th&gt;
      &lt;th&gt;Levels&lt;/th&gt;
      &lt;th&gt;Shortest solution (moves)&lt;/th&gt;
      &lt;th&gt;Move budget&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Warm-up&lt;/td&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;exactly 5&lt;/td&gt;
      &lt;td&gt;7&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Tactics&lt;/td&gt;
      &lt;td&gt;12&lt;/td&gt;
      &lt;td&gt;exactly 6&lt;/td&gt;
      &lt;td&gt;8&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Pressure&lt;/td&gt;
      &lt;td&gt;12&lt;/td&gt;
      &lt;td&gt;exactly 7&lt;/td&gt;
      &lt;td&gt;8-9&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Precision&lt;/td&gt;
      &lt;td&gt;12&lt;/td&gt;
      &lt;td&gt;exactly 8&lt;/td&gt;
      &lt;td&gt;9-10&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Deep Water&lt;/td&gt;
      &lt;td&gt;12&lt;/td&gt;
      &lt;td&gt;exactly 9&lt;/td&gt;
      &lt;td&gt;9-11&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Mastery&lt;/td&gt;
      &lt;td&gt;12&lt;/td&gt;
      &lt;td&gt;10 to 16&lt;/td&gt;
      &lt;td&gt;12-16&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;what-the-earlier-puzzle-mode-got-wrong&quot;&gt;What the earlier puzzle mode got wrong&lt;/h2&gt;

&lt;p&gt;An earlier version of this game’s puzzle mode shipped 22 puzzles, and a test confirmed each had a solution. When I finally solved all 22 exhaustively, the mean shortest solution was 1.91 moves. “Up, then left” solved 19 of them. Random play won at least 98% of the time on 20, and even the hardest fell to it two times in three. One could not be lost by any legal sequence. Nine were the same board with different numbers printed on the tiles.&lt;/p&gt;

&lt;p&gt;The cause was structural. Nothing arrived on those boards, so every move made the position easier, and every goal was monotone: once reached, nothing could undo it. No position could be ruined, and a puzzle needs a way to go wrong. The test only asked whether a solution existed, which sets a floor and no ceiling.&lt;/p&gt;

&lt;h2 id=&quot;why-greedy-friendly-goals-fail&quot;&gt;Why greedy-friendly goals fail&lt;/h2&gt;

&lt;p&gt;I assumed the old goals only needed a failure rule. Of 400 forged candidates for “clear the board down to N tiles”, 215 reached the target depth and none passed. Of 400 for “reach a tile of at least T”, 100 reached it and none passed. “Deliver an exact value to a marked cell” passed readily.&lt;/p&gt;

&lt;p&gt;The reason is almost embarrassing once written down. A goal that a one-move greedy metric directly optimises can never be a puzzle. A player who grabs the most empty cells &lt;em&gt;is&lt;/em&gt; pursuing the clearing goal; one who grabs the biggest tile &lt;em&gt;is&lt;/em&gt; pursuing the reach goal. The clearing goal fell to the dumbest strategies in the battery: one direction over and over, or a fixed cycle.&lt;/p&gt;

&lt;p&gt;Delivery survives because it can be lost twice over. The target must rest on one cell, so sliding it off loses it. It must also be an exact value, so merging past it (building a 128 when the level asked for a 64) loses it for good. No local score approximates either condition. Millrace has exactly one kind of goal because the measurements left only one.&lt;/p&gt;

&lt;h2 id=&quot;why-you-can-see-every-tile-before-it-arrives&quot;&gt;Why you can see every tile before it arrives&lt;/h2&gt;

&lt;p&gt;The other half of the fix is the arrival queue. Tiles, only 2s and 4s, enter one at a time through a single inlet on the board’s edge. If the inlet is occupied when the next one is due, the run ends. That brings back the tension a slide-and-merge board depends on, because it fills while you merge.&lt;/p&gt;

&lt;p&gt;Chance stays out. The queue is authored and always on screen, so every position is a pure function of the moves played, with at most four moves from each. With random arrivals, “the shortest solution” isn’t a number, since it depends on tiles nobody has drawn, and a solver can only average over futures. With a visible queue there is nothing to average, and breadth-first search is the exact model. The gate knows exactly what you know.&lt;/p&gt;

&lt;h2 id=&quot;how-a-candidate-level-is-generated&quot;&gt;How a candidate level is generated&lt;/h2&gt;

&lt;p&gt;The generator is simple, and the rigour sits in the gate. A candidate gets a vault on an edge cell (never a corner, which would be marked twice) and a scatter of tiles from 2 to 32. The inlet is chosen last, from edge cells no opening slide can fill; when it was picked first, most candidates buried their own inlet on move one. The target is one or two doublings above the biggest starting tile, followed by a queue of 2s and 4s. A candidate whose tiles cannot sum to the target is dropped before any search runs.&lt;/p&gt;

&lt;p&gt;The solver measures the true shortest solution under the gate’s most generous budget, 16 moves, and the candidate stays only if that depth is what the chapter demands. It tries two spare moves, then one, then none, keeping the kindest budget that passes. Depending on the chapter, roughly one to eight candidates in a thousand make it.&lt;/p&gt;

&lt;h2 id=&quot;280-thoughtless-players-and-one-random-one&quot;&gt;280 thoughtless players, and one random one&lt;/h2&gt;

&lt;p&gt;The battery in the middle of the gate has 4 policies that push one direction until they can’t, 60 that cycle through two, three or four directions, 24 fixed priority orders, 72 greedy players chasing points, empty cells or the biggest tile under all 24 tiebreak orders, and 120 that know the rules. Those last ones keep the inlet clear, keep it clear then score, avoid losing on this move, herd the biggest tile to a corner, or chase the target onto the vault, again under all 24 orders. Each is deterministic, so one playthrough counts as a proof. A level ships only if all 280 fail.&lt;/p&gt;

&lt;p&gt;The battery’s first version was circular. Its 70 policies never looked at the inlet, so “none of them solves it” only meant “players who ignore the inlet die to the inlet”. Adding rule-aware players broke six of the eight puzzles that had passed it.&lt;/p&gt;

&lt;p&gt;The line sits at one move on purpose. Looking two moves ahead (where will the next arrival land?) isn’t thoughtless, and it is the skill the levels teach. The gate certifies that the content has depth; it doesn’t assume you can’t think. &lt;a href=&quot;/journal/how-to-plan-moves-ahead-in-tile-puzzles/&quot;&gt;How to plan moves ahead in Millrace&lt;/a&gt; shows that lookahead in play, with Level 1 worked move by move.&lt;/p&gt;

&lt;p&gt;Chance gets the same treatment. The move budget makes each level’s state graph finite and loop-free, so a random player’s odds are computed exactly by a memoised walk instead of a simulation. The ceiling is 2%, Warm-up included. Across the 64 levels the odds run from about one in a million on the deepest boards to 1.31% on Level 1, with the median near one in a thousand.&lt;/p&gt;

&lt;p&gt;Finally, no two levels may share a canonical form: tile values replaced by rank, then the smallest of the eight rotations and reflections of board, inlet, vault and queue together. That check exists because of those nine identical boards.&lt;/p&gt;

&lt;h2 id=&quot;why-the-gate-lives-in-the-test-suite&quot;&gt;Why the gate lives in the test suite&lt;/h2&gt;

&lt;p&gt;The sixteen checks live in the test target and run every time, not once. The generator filters with the same functions, and the suite asserts each property over the shipped library, so a level that stops passing fails the tests and names the property that broke. A search that runs out of budget fails too, since an unproven level can’t ship. The gate also has to prove itself: a board from the earlier library is kept as a fixture, and the suite fails if it ever gets through. Re-proving all 64 levels takes just under a hundred seconds. Tare’s balance puzzles are built by hand, but they pass the same kind of gate; &lt;a href=&quot;/journal/how-to-solve-balance-puzzles/&quot;&gt;here is how it proves each level&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The Hint inside a level runs the same solver, so the two cannot drift apart, and one check plays every level on the hint alone: it must win in exactly the shortest number of moves. For &lt;a href=&quot;/journal/forty-chess-opponents/&quot;&gt;Chessful’s forty opponents&lt;/a&gt;, difficulty was a matter of character. Here it had to be a number the tests check.&lt;/p&gt;

&lt;h2 id=&quot;what-you-see-of-it&quot;&gt;What you see of it&lt;/h2&gt;

&lt;p&gt;Almost none of this is on screen.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The chapter is the depth. Every Tactics level can be solved in six moves and no fewer; every Deep Water level, in nine. In chess, depth is an engine setting, and &lt;a href=&quot;/journal/engine-depth-at-club-level-tune-down/&quot;&gt;more of it doesn’t help a club player&lt;/a&gt;. Here it is a measured property of the board.&lt;/li&gt;
  &lt;li&gt;The budget is tight. The deepest level needs all 16 of its 16 moves.&lt;/li&gt;
  &lt;li&gt;The result card says “Solved in N moves”, and if you used more, “Best possible is X moves”, where X is the proven minimum.&lt;/li&gt;
  &lt;li&gt;A loss can say when it happened. After a failed run, the card can name the move where the position became unwinnable. It only does so afterwards, because a live warning turns a level into trial and error, and you reach the answer having understood nothing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Millrace is free on iPhone and iPad; the &lt;a href=&quot;/apps/millrace/&quot;&gt;app page&lt;/a&gt; has the rules and the privacy details. If a level ever feels impossible, somewhere in its graph is a line exactly as long as the card says, and the tests have walked it.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>Promotional text vs description: which App Store fields you can change without an update</title>
    <link href="https://lagerland-apps.github.io/journal/app-store-fields-that-need-a-new-version/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/app-store-fields-that-need-a-new-version/</id>
    <published>2026-09-19T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Half the App Store product page is frozen until your next update, and the other half you can change on a Tuesday afternoon. Apple documents which is which, but across four or five different help pages. This is all of it in one table, checked against Apple&apos;s current pages, with the two places most people get it wrong.</summary>
    <content type="html">&lt;p&gt;App Store Connect splits your product page into things you can change on the live app and things that wait for the next version. Apple’s &lt;a href=&quot;https://developer.apple.com/help/app-store-connect/reference/app-information/required-localizable-and-editable-properties&quot;&gt;table of required, localizable and editable properties&lt;/a&gt; marks the properties that “can be localized and edited at any time without submitting a new version of your app.” Everything else changes with a version.&lt;/p&gt;

&lt;h2 id=&quot;which-app-store-fields-need-a-new-version&quot;&gt;Which App Store fields need a new version?&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Field&lt;/th&gt;
      &lt;th&gt;Lives in&lt;/th&gt;
      &lt;th&gt;Limit&lt;/th&gt;
      &lt;th&gt;When you can change it&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Promotional text&lt;/td&gt;
      &lt;td&gt;Version&lt;/td&gt;
      &lt;td&gt;170 characters&lt;/td&gt;
      &lt;td&gt;Any time, no new version&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Description&lt;/td&gt;
      &lt;td&gt;Version&lt;/td&gt;
      &lt;td&gt;4,000 characters&lt;/td&gt;
      &lt;td&gt;With a new version&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Keywords&lt;/td&gt;
      &lt;td&gt;Version&lt;/td&gt;
      &lt;td&gt;100 characters&lt;/td&gt;
      &lt;td&gt;With a new version&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;What’s New&lt;/td&gt;
      &lt;td&gt;Version&lt;/td&gt;
      &lt;td&gt;4,000 characters&lt;/td&gt;
      &lt;td&gt;With a new version (not on the first version)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Screenshots&lt;/td&gt;
      &lt;td&gt;Version&lt;/td&gt;
      &lt;td&gt;Up to 10 per display size&lt;/td&gt;
      &lt;td&gt;With a new version&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;App previews&lt;/td&gt;
      &lt;td&gt;Version&lt;/td&gt;
      &lt;td&gt;Up to 3 per localization and display size&lt;/td&gt;
      &lt;td&gt;With a new version&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Support URL, marketing URL&lt;/td&gt;
      &lt;td&gt;Version&lt;/td&gt;
      &lt;td&gt;Full URL&lt;/td&gt;
      &lt;td&gt;With a new version&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Copyright&lt;/td&gt;
      &lt;td&gt;Version&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;Any time&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;App Review information&lt;/td&gt;
      &lt;td&gt;Version&lt;/td&gt;
      &lt;td&gt;Notes up to 4,000 bytes&lt;/td&gt;
      &lt;td&gt;Any time&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;App name&lt;/td&gt;
      &lt;td&gt;App Information&lt;/td&gt;
      &lt;td&gt;30 characters&lt;/td&gt;
      &lt;td&gt;With a new version&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Subtitle&lt;/td&gt;
      &lt;td&gt;App Information&lt;/td&gt;
      &lt;td&gt;30 characters&lt;/td&gt;
      &lt;td&gt;With a new version&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Primary and secondary category&lt;/td&gt;
      &lt;td&gt;App Information&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;With a new version&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Age rating&lt;/td&gt;
      &lt;td&gt;App Information&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;With a new version&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Primary language&lt;/td&gt;
      &lt;td&gt;App Information&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;Any time&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Privacy policy URL&lt;/td&gt;
      &lt;td&gt;App Privacy&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;With a new version&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;App Privacy data types&lt;/td&gt;
      &lt;td&gt;App Privacy&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;Any time&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Price and availability&lt;/td&gt;
      &lt;td&gt;Pricing and Availability&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;Any time&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;App icon&lt;/td&gt;
      &lt;td&gt;Your build&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;With a new version and a new build&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Sources: the editable-properties table above, Apple’s &lt;a href=&quot;https://developer.apple.com/help/app-store-connect/reference/app-information/platform-version-information/&quot;&gt;Platform version information&lt;/a&gt; reference, its &lt;a href=&quot;https://developer.apple.com/app-store/product-page/&quot;&gt;product page guide&lt;/a&gt;, and the &lt;a href=&quot;https://developer.apple.com/help/app-store-connect/manage-app-information/add-an-app-icon&quot;&gt;Add an app icon&lt;/a&gt; page, which says changing the icon after publishing means creating and uploading a new version.&lt;/p&gt;

&lt;h2 id=&quot;promotional-text-vs-description-whats-the-difference&quot;&gt;Promotional text vs description: what’s the difference?&lt;/h2&gt;

&lt;p&gt;They sit next to each other on the product page, but Apple treats them differently.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; &lt;/th&gt;
      &lt;th&gt;Promotional text&lt;/th&gt;
      &lt;th&gt;Description&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Length&lt;/td&gt;
      &lt;td&gt;Up to 170 characters&lt;/td&gt;
      &lt;td&gt;Up to 4,000 characters, plain text, no HTML&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Position&lt;/td&gt;
      &lt;td&gt;At the top of the description&lt;/td&gt;
      &lt;td&gt;Below the promotional text&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;When it changes&lt;/td&gt;
      &lt;td&gt;Any time, without a new version&lt;/td&gt;
      &lt;td&gt;With a new version&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Search&lt;/td&gt;
      &lt;td&gt;Apple says it doesn’t affect search ranking&lt;/td&gt;
      &lt;td&gt;Not listed among App Store search factors; used for web search engine results&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Apple’s suggested use&lt;/td&gt;
      &lt;td&gt;Current news: limited-time sales, upcoming features&lt;/td&gt;
      &lt;td&gt;What the app does; the first sentence is what people read without tapping more&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The practical rule follows from the third row. Anything that will be out of date in a month (a sale, a seasonal event, a feature that’s coming soon) goes in promotional text, because you can take it out again without shipping. Anything that should stay true for the life of a version goes in the description. Apple also says to leave specific prices out of the description, which is easier to follow once you know the promotional text is the place for a sale.&lt;/p&gt;

&lt;p&gt;Putting keywords into promotional text doesn’t help. Apple says so on both its &lt;a href=&quot;https://developer.apple.com/app-store/search/&quot;&gt;search&lt;/a&gt; and product page guides, and the &lt;a href=&quot;/journal/app-store-keyword-field-100-characters/&quot;&gt;keyword field&lt;/a&gt; has its own rules.&lt;/p&gt;

&lt;h2 id=&quot;whats-the-difference-between-app-information-and-version-information&quot;&gt;What’s the difference between App Information and version information?&lt;/h2&gt;

&lt;p&gt;App Store Connect has two places for metadata, and the API mirrors them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;App Information&lt;/strong&gt; is shared across all versions and platforms of the app. In the App Store Connect API it’s an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;appInfoLocalizations&lt;/code&gt; record holding the name, subtitle, privacy policy URL and privacy choices URL, with the categories and age rating on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;appInfo&lt;/code&gt; itself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Platform version information&lt;/strong&gt; belongs to one version on one platform. Its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;appStoreVersionLocalizations&lt;/code&gt; record holds the description, keywords, promotional text, What’s New, support URL and marketing URL, and the version also carries the screenshots, app previews, copyright, version number, App Review information and release settings.&lt;/p&gt;

&lt;p&gt;That split explains the first trap. App Information isn’t tied to a version, so it’s easy to assume you can edit it any time, and for most of it you can’t. Apple’s table marks the name, subtitle, categories, age rating and privacy policy URL as not editable at any time, and the product page guide ties subtitle changes to a new version. In the API, while an update is in preparation the app has two App Info records, one for the live version and one for the update, and the update’s record is the one you edit.&lt;/p&gt;

&lt;p&gt;The second trap is the promotional text itself. It is a version field, stored right next to the description, yet it’s the only marketing copy you can change on a version that’s already live. Tools that lock every version field once a version is approved get this one wrong, AppMeta included for now (more on that below).&lt;/p&gt;

&lt;h2 id=&quot;when-does-a-version-accept-edits&quot;&gt;When does a version accept edits?&lt;/h2&gt;

&lt;p&gt;Apple lists the statuses in which you can upload and submit screenshots for a version: Prepare for Submission, Invalid Binary, Rejected, Metadata Rejected and Developer Rejected (&lt;a href=&quot;https://developer.apple.com/help/app-store-connect/manage-app-information/upload-app-previews-and-screenshots&quot;&gt;Apple’s screenshot upload help&lt;/a&gt;). In other words, a version you’re preparing or one that came back from review. If you spot a mistake after submitting, Apple’s route is to remove the version from review, which sets it back to Developer Rejected; the review starts over when you resubmit (&lt;a href=&quot;https://developer.apple.com/help/app-store-connect/manage-submissions-to-app-review/remove-a-submission-from-review&quot;&gt;Remove a submission from review&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;To start a new version, the current one has to be Ready for Distribution. App Store Connect copies the live version’s metadata into the new one, so a description fix starts from what’s already there (&lt;a href=&quot;https://developer.apple.com/help/app-store-connect/update-your-app/create-a-new-version&quot;&gt;Create a new version&lt;/a&gt;). You still need a build: a version can’t be submitted without one, and Apple’s steps include uploading a new build with an incremented build string. So a description-only update is still a full release with a new binary.&lt;/p&gt;

&lt;h2 id=&quot;what-can-you-change-without-a-new-version&quot;&gt;What can you change without a new version?&lt;/h2&gt;

&lt;p&gt;Beyond promotional text, Apple’s editable-properties table marks these as editable at any time:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Price, pricing start and end dates, availability, the pre-order release date, tax category and the last-compatible version setting&lt;/li&gt;
  &lt;li&gt;App Privacy data types (the privacy label)&lt;/li&gt;
  &lt;li&gt;App Review information and copyright&lt;/li&gt;
  &lt;li&gt;Primary language and the custom license agreement&lt;/li&gt;
  &lt;li&gt;The routing app coverage file, for navigation apps&lt;/li&gt;
  &lt;li&gt;Accessibility support, for the Accessibility Nutrition Labels&lt;/li&gt;
  &lt;li&gt;Phased release, which you can pause within its seven-day window&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Several review tracks also run without a new app version once your app has an approved one:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Track&lt;/th&gt;
      &lt;th&gt;What it changes&lt;/th&gt;
      &lt;th&gt;Apple’s rule&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Custom product pages&lt;/td&gt;
      &lt;td&gt;Screenshots, app previews, promotional text and keywords on an alternate page, up to 70 per app&lt;/td&gt;
      &lt;td&gt;Submit with or without an iOS app version; keywords come from your latest approved version&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Product page optimization&lt;/td&gt;
      &lt;td&gt;Up to three treatments of icons, screenshots and previews, for up to 90 days&lt;/td&gt;
      &lt;td&gt;Tests without alternate app icons can be submitted independently of a new version&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;In-App Events&lt;/td&gt;
      &lt;td&gt;Event cards and details&lt;/td&gt;
      &lt;td&gt;Submit with or without an iOS app version&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;In-App Purchases&lt;/td&gt;
      &lt;td&gt;New products and their metadata&lt;/td&gt;
      &lt;td&gt;Only the first product of each type needs a new app version&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The custom product page rules are on Apple’s &lt;a href=&quot;https://developer.apple.com/help/app-store-connect/manage-submissions-to-app-review/submit-a-custom-product-page&quot;&gt;submission page&lt;/a&gt;, the test rules on its &lt;a href=&quot;https://developer.apple.com/app-store/product-page-optimization/&quot;&gt;product page optimization page&lt;/a&gt;, and the In-App Purchase rule was clarified in Apple’s &lt;a href=&quot;https://developer.apple.com/help/app-store-connect/release-notes/&quot;&gt;release notes&lt;/a&gt; on August 19, 2026. A product page optimization test can’t change your default page’s screenshots by itself, but if a treatment wins, Apple lets you apply it to the original product page.&lt;/p&gt;

&lt;h2 id=&quot;how-i-plan-around-it&quot;&gt;How I plan around it&lt;/h2&gt;

&lt;p&gt;When a version is in Prepare for Submission, I go through every version field and every App Information field in every localization, because that window is the only time most of them open. Between versions, the levers are promotional text and the review tracks above.&lt;/p&gt;

&lt;p&gt;Screenshots follow the same window, and the &lt;a href=&quot;/journal/app-store-screenshot-review-guidelines-explained/&quot;&gt;screenshot guidelines post&lt;/a&gt; covers what App Review checks in them. The keyword field is the one I plan furthest ahead, because a keyword change waits for a version just like a description change does.&lt;/p&gt;

&lt;h2 id=&quot;where-appmeta-fits&quot;&gt;Where AppMeta fits&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/apps/appmeta/&quot;&gt;AppMeta&lt;/a&gt; keeps the same split App Store Connect does. App Information fields (name, subtitle, privacy policy URL) and version fields are separate sections, and each push goes to the right API record. When the newest version on a platform is live, in review or waiting for release, AppMeta locks its version fields and says why, and you can create the next version from inside the app, then copy fields over from the previous one. Before anything is pushed, the preview shows the current App Store Connect value next to your change for every field and localization. AppMeta signs in with an API key you create yourself; the &lt;a href=&quot;/journal/app-store-connect-api-key-setup/&quot;&gt;setup guide&lt;/a&gt; walks through it.&lt;/p&gt;

&lt;p&gt;AppMeta has one gap: it applies that version lock to promotional text too. To change promotional text on a live version with no update in progress, use the App Store Connect website for now.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>How to sleep on call: the waiting, the wake-up and the morning after</title>
    <link href="https://lagerland-apps.github.io/journal/how-to-sleep-on-call/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/how-to-sleep-on-call/</id>
    <published>2026-09-12T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Being on call costs sleep even on nights when nobody calls. Studies of ships&apos; engineers, doctors, firefighters and other on-call workers point at two separate problems: the waiting, which keeps sleep light before any call comes, and the wake-up, when grogginess is at its worst. This post sums up that research and what it means for naps, caffeine and the morning after.</summary>
    <content type="html">&lt;p&gt;On-call work means being available outside your rostered hours, at home or on site, for a call that may or may not come. Doctors, nurses, firefighters, engineers, IT staff and utility crews all do it. The studies below look at people on call overnight; some measured real call-outs, others only the possibility of one.&lt;/p&gt;

&lt;h2 id=&quot;what-does-the-research-say-about-sleep-on-call&quot;&gt;What does the research say about sleep on call?&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Study&lt;/th&gt;
      &lt;th&gt;Who&lt;/th&gt;
      &lt;th&gt;What it found&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://pubmed.ncbi.nlm.nih.gov/3363267/&quot;&gt;Torsvall &amp;amp; Åkerstedt, 1988&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;5 ships’ engineers, EEG&lt;/td&gt;
      &lt;td&gt;On-call nights with two alarms had shorter sleep, less deep and REM sleep, and a higher heart rate. Many of the changes appeared before any alarm. Sleepiness was higher the next day.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://pubmed.ncbi.nlm.nih.gov/27426960/&quot;&gt;Hall et al., 2017&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;Systematic review of 8 studies&lt;/td&gt;
      &lt;td&gt;Being on call from home appears to reduce sleep quantity and, in most studies, sleep quality. None separated nights with calls from nights without.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://pubmed.ncbi.nlm.nih.gov/32106711/&quot;&gt;Vincent et al., 2021&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;Survey of 228 Australian on-call workers&lt;/td&gt;
      &lt;td&gt;80% slept under 7 hours when on call; 56% said being on call affected their sleep even when no calls came.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://pubmed.ncbi.nlm.nih.gov/32941345/&quot;&gt;Marcel-Millet et al., 2020&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;13 firefighters&lt;/td&gt;
      &lt;td&gt;Parasympathetic heart-rate variability, a sign of the body settling, was lower on on-call nights with or without a simulated call-out. Sleep time and rated quality fell on the night with a call-out.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://pubmed.ncbi.nlm.nih.gov/31479838/&quot;&gt;Kovac et al., 2020&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;23 young men in a sleep lab&lt;/td&gt;
      &lt;td&gt;Told they might be woken but never were, they slept about 7.5 hours, yet felt sleepier after waking than on a normal night.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://pubmed.ncbi.nlm.nih.gov/15647575/&quot;&gt;Barger et al., 2005&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;2,737 first-year doctors&lt;/td&gt;
      &lt;td&gt;After shifts of 24 hours or more, the odds of reporting a car crash were 2.3 times higher and of a near miss 5.9 times higher.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Two findings run through the list: sleep on call is worse even when the phone stays quiet, and the moments after a call wakes you carry their own risk.&lt;/p&gt;

&lt;h2 id=&quot;why-does-being-on-call-cost-sleep-even-when-nobody-calls&quot;&gt;Why does being on call cost sleep even when nobody calls?&lt;/h2&gt;

&lt;p&gt;The engineers in the 1988 study slept worse before any alarm had sounded, and the authors attributed it to apprehension about being woken. The Australian survey asked on-call workers what they turned over in their heads. The top answers were interruptions to family and leisure time (70%), missing a call (69%), planning in case of a call (69%) and not being able to make plans (67%).&lt;/p&gt;

&lt;p&gt;Not every study finds the worry in the sleep itself. In two lab studies from the same Australian group (&lt;a href=&quot;https://pubmed.ncbi.nlm.nih.gov/29682871/&quot;&gt;Sprajcer et al., 2018&lt;/a&gt; and Kovac et al.), telling young men they would face a stressful task rather than an easy one if woken made no difference to how they slept. A lab bedroom with nothing real at stake differs from a bedroom with a pager on the table, though, and the field studies and surveys fairly consistently find real on-call nights shorter and lighter.&lt;/p&gt;

&lt;p&gt;The survey doesn’t test fixes, but its list suggests where to start. If the worry is missing the call, make that close to impossible: one alert you have tested at full volume, and Do Not Disturb set so only the call-out number gets through. If it’s the planning, do it before bed. Clothes, keys, bag and charger in one place leave nothing to rehearse in the dark.&lt;/p&gt;

&lt;h2 id=&quot;what-is-sleep-inertia-and-how-long-does-it-last&quot;&gt;What is sleep inertia, and how long does it last?&lt;/h2&gt;

&lt;p&gt;Sleep inertia is the grogginess and slowed thinking right after waking. A &lt;a href=&quot;https://pmc.ncbi.nlm.nih.gov/articles/PMC6710480/&quot;&gt;2019 review by Hilditch and McHill&lt;/a&gt; sets out its shape:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;It is worst in the first 15 to 30 minutes and then fades, but full recovery can take an hour or more.&lt;/li&gt;
  &lt;li&gt;It is worse after sleep loss, and worse when you wake near the low point of your body clock in the early hours of the morning.&lt;/li&gt;
  &lt;li&gt;Right after waking, the impairment can match or exceed that seen after up to 40 hours without sleep.&lt;/li&gt;
  &lt;li&gt;Naps of 30 minutes or less are less likely to cause it, though not immune.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On call, these add up. A call that wakes you at 3 a.m. after a short night lands on close to the worst version of inertia there is. Where you can, put the minutes it takes to dress and get moving before anything that needs judgement, and check the first decision twice.&lt;/p&gt;

&lt;h2 id=&quot;can-caffeine-or-light-shake-off-sleep-inertia&quot;&gt;Can caffeine or light shake off sleep inertia?&lt;/h2&gt;

&lt;p&gt;The same review rates the countermeasures. Caffeine taken just before a short nap of about 20 minutes has the best support, because it starts working around the time you wake. Caffeine gum after waking shortened inertia but didn’t help the worst first stretch. Bright light, sound and cooling have weak or early evidence, and no reactive fix has clear, immediate benefit.&lt;/p&gt;

&lt;p&gt;In &lt;a href=&quot;https://pubmed.ncbi.nlm.nih.gov/9401427/&quot;&gt;Reyner and Horne’s 1997 driving-simulator study&lt;/a&gt;, sleepy drivers given 200 mg of caffeine plus a nap of under 15 minutes had 9% as many driving incidents as on placebo, against 34% with caffeine alone.&lt;/p&gt;

&lt;p&gt;On call, caffeine has a cost it doesn’t have on a normal shift: you may want to go back to sleep. A &lt;a href=&quot;https://pmc.ncbi.nlm.nih.gov/articles/PMC8980688/&quot;&gt;2022 review on switching on for a call and switching off after it&lt;/a&gt; points out that whatever wakes you up for a call may also keep you from falling asleep afterwards, and that this hasn’t been studied well yet. Caffeine’s half-life is about 5 to 6 hours (&lt;a href=&quot;/journal/how-to-sleep-after-a-night-shift/&quot;&gt;the night-shift guide&lt;/a&gt; does the arithmetic), so a coffee at 2 a.m. for a twenty-minute call is still mostly in you at 6. It makes sense to save it for calls that will keep you up, or for the drive.&lt;/p&gt;

&lt;h2 id=&quot;how-should-you-nap-when-youre-on-call&quot;&gt;How should you nap when you’re on call?&lt;/h2&gt;

&lt;p&gt;When your sleep might be broken at any moment, sleep you get before the call is worth more than sleep you plan to get after it. That makes short naps the main tool. If you might have to act straight away on waking, Hilditch and McHill suggest keeping naps under 30 minutes. NIOSH’s shift-work course &lt;a href=&quot;https://www.cdc.gov/niosh/work-hour-training-for-nurses/longhours/mod7/05.html&quot;&gt;adds&lt;/a&gt; that waking after about 20 or about 90 minutes tends to leave you less groggy than waking after about an hour.&lt;/p&gt;

&lt;p&gt;A &lt;a href=&quot;https://pubmed.ncbi.nlm.nih.gov/39388823/&quot;&gt;2025 review of fatigue guidance for on-call workers&lt;/a&gt; went through 65 guidance documents from regulators and 17 studies of what works. It found very little research outside limits on working hours. Training, education and call management, such as protected naps during on-call periods, were among the few measures with some supporting evidence.&lt;/p&gt;

&lt;h2 id=&quot;what-should-you-do-after-a-night-of-calls&quot;&gt;What should you do after a night of calls?&lt;/h2&gt;

&lt;p&gt;Treat it like the morning after a night shift, because for your body it was one. The drive home is the riskiest part. In Barger’s study of first-year doctors, each extended shift scheduled in a month raised the monthly risk of a crash on the commute home by about 16%. Get a lift if you can, nap before you drive if you can’t, and see the &lt;a href=&quot;/journal/how-to-sleep-after-a-night-shift/&quot;&gt;night-shift guide&lt;/a&gt; for the dark room and the rest of the morning.&lt;/p&gt;

&lt;p&gt;Then expect recovery to take more than one night. In a lab study by &lt;a href=&quot;https://pmc.ncbi.nlm.nih.gov/articles/PMC2910531/&quot;&gt;Banks and colleagues (2010)&lt;/a&gt;, people limited to 4 hours in bed for five nights had still not fully recovered on attention, sleepiness and fatigue measures after a single 10-hour night in bed. A week of broken on-call nights is a different experiment, but the result points the same way: one long sleep helps, and it may not be enough.&lt;/p&gt;

&lt;p&gt;If you are on call often and your sleep doesn’t recover between stretches, raise it with your employer’s fatigue policy and with a doctor. The American Academy of Sleep Medicine’s page on &lt;a href=&quot;https://sleepeducation.org/sleep-disorders/shift-work/&quot;&gt;shift work disorder&lt;/a&gt; describes when poor sleep around work hours becomes a clinical problem.&lt;/p&gt;

&lt;h2 id=&quot;where-aftershift-fits&quot;&gt;Where AfterShift fits&lt;/h2&gt;

&lt;p&gt;On-call is a shift type in &lt;a href=&quot;/apps/aftershift/&quot;&gt;AfterShift&lt;/a&gt;, and it changes how the app treats the whole window around it. Calendar import recognises event titles such as on call, standby, backup, Bereitschaft or päivystys, and you can mark any shift as on-call yourself. When the window between your shifts contains an on-call shift:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The Shift Recovery Score is capped at 75 and the Sleep Score at 84, so neither can read Excellent. I did that on purpose. The studies above find on-call sleep is worse even before any call comes, and a perfect-looking number in a week of broken nights would be the app claiming to know more than it does.&lt;/li&gt;
  &lt;li&gt;The plan shows a flexible rest window instead of a set main sleep, and the nap suggestion says short naps are often more reliable on call. The short-window warning is switched off, since a short window is normal on call.&lt;/li&gt;
  &lt;li&gt;In Premium, the playbook switches to a standby routine when an on-call shift starts within the next 12 hours: lay out what you’ll need and keep the path to the door clear, keep caffeine for the shift, and wind down lightly so you stay easy to wake.&lt;/li&gt;
  &lt;li&gt;Three or more on-call shifts in seven days count as an on-call week, and the app notes that recovery may come more slowly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Naps you log count toward the score like any other sleep, which matters on call, where they may be most of what you get. The &lt;a href=&quot;/apps/aftershift/methodology/&quot;&gt;methodology page&lt;/a&gt; explains the caps, and the &lt;a href=&quot;/journal/rotating-shift-schedules-explained/&quot;&gt;rotating schedules guide&lt;/a&gt; covers the rosters that on-call weeks usually sit inside.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>Double progression explained: add reps until the range runs out, then add weight</title>
    <link href="https://lagerland-apps.github.io/journal/double-progression-explained/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/double-progression-explained/</id>
    <published>2026-09-05T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Linear progression asks the bar to get heavier every session, and on most lifts that stops working within months. What usually comes next is double progression: the weight stays put while the reps climb through a range, and only then does the load go up. It is simple to describe and easy to run badly. This post covers the rules, eight sessions worked through, what a small plate adds in percent, and the signs it has run its course.</summary>
    <content type="html">&lt;p&gt;Most strength programs start with linear progression: a little more weight every session. On most lifts it works for a few months and then stops, usually on the press first. How to tell when that phase is over is in &lt;a href=&quot;/journal/choosing-a-strength-program-you-will-finish/&quot;&gt;choosing a strength program you will finish&lt;/a&gt;. What most people run next is double progression. It is also the default rule in the strength log I build, so this is the long version.&lt;/p&gt;

&lt;h2 id=&quot;what-is-double-progression&quot;&gt;What is double progression?&lt;/h2&gt;

&lt;p&gt;You progress two things in a fixed order: reps first, at a weight you keep, then load, once the reps have run out of room.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Part of the rule&lt;/th&gt;
      &lt;th&gt;What it means&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Rep range&lt;/td&gt;
      &lt;td&gt;A bracket for every working set, written sets × bottom-top: 3 × 6-10&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Hold&lt;/td&gt;
      &lt;td&gt;Keep the weight while any set is short of the top of the range&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Add load&lt;/td&gt;
      &lt;td&gt;When every working set reaches the top, add the smallest increment you have&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Reset&lt;/td&gt;
      &lt;td&gt;At the new weight, expect to be back near the bottom of the range&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Bad session&lt;/td&gt;
      &lt;td&gt;A set below the bottom is a miss. Repeat the weight. Only several misses in a row call for a lighter restart&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;None of this is new. The American College of Sports Medicine’s 2009 position stand on progression lists increasing load within a prescribed zone, its example being 8-12 RM, as one of three ways to progress. Its rule for when to move is a 2-10% increase once you can do one or two reps more than the target on two consecutive sessions, at the lower end for small-muscle exercises (&lt;a href=&quot;https://pubmed.ncbi.nlm.nih.gov/19204579/&quot;&gt;ACSM, 2009&lt;/a&gt;). Double progression is that rule with the bookkeeping written down.&lt;/p&gt;

&lt;h2 id=&quot;a-worked-example-eight-sessions-of-overhead-press&quot;&gt;A worked example: eight sessions of overhead press&lt;/h2&gt;

&lt;p&gt;Barbell overhead press, 3 × 6-10, starting at 40 kg. The smallest jump in this gym is 2.5 kg.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Session&lt;/th&gt;
      &lt;th&gt;Load&lt;/th&gt;
      &lt;th&gt;Reps (set 1 / 2 / 3)&lt;/th&gt;
      &lt;th&gt;Total reps&lt;/th&gt;
      &lt;th&gt;Next session&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;40 kg&lt;/td&gt;
      &lt;td&gt;10 / 8 / 7&lt;/td&gt;
      &lt;td&gt;25&lt;/td&gt;
      &lt;td&gt;Same weight&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2&lt;/td&gt;
      &lt;td&gt;40 kg&lt;/td&gt;
      &lt;td&gt;10 / 9 / 8&lt;/td&gt;
      &lt;td&gt;27&lt;/td&gt;
      &lt;td&gt;Same weight&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;40 kg&lt;/td&gt;
      &lt;td&gt;10 / 10 / 8&lt;/td&gt;
      &lt;td&gt;28&lt;/td&gt;
      &lt;td&gt;Same weight&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;40 kg&lt;/td&gt;
      &lt;td&gt;10 / 10 / 10&lt;/td&gt;
      &lt;td&gt;30&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;Add 2.5 kg&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;5&lt;/td&gt;
      &lt;td&gt;42.5 kg&lt;/td&gt;
      &lt;td&gt;8 / 7 / 6&lt;/td&gt;
      &lt;td&gt;21&lt;/td&gt;
      &lt;td&gt;Same weight&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;6&lt;/td&gt;
      &lt;td&gt;42.5 kg&lt;/td&gt;
      &lt;td&gt;8 / 7 / 5&lt;/td&gt;
      &lt;td&gt;20&lt;/td&gt;
      &lt;td&gt;Same weight (set 3 missed)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;7&lt;/td&gt;
      &lt;td&gt;42.5 kg&lt;/td&gt;
      &lt;td&gt;9 / 8 / 7&lt;/td&gt;
      &lt;td&gt;24&lt;/td&gt;
      &lt;td&gt;Same weight&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;8&lt;/td&gt;
      &lt;td&gt;42.5 kg&lt;/td&gt;
      &lt;td&gt;10 / 9 / 8&lt;/td&gt;
      &lt;td&gt;27&lt;/td&gt;
      &lt;td&gt;Same weight&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Sessions 1 to 4 are the easy part: the weight never changes while the total climbs from 25 reps to 30, and session 4 is the first time all three sets reach ten.&lt;/p&gt;

&lt;p&gt;Session 5 is where people lose faith. Going from 10, 10, 10 to 8, 7, 6 looks like a step backwards. It is the plan working: every set is inside the range at a heavier weight, and the climb starts again.&lt;/p&gt;

&lt;p&gt;Session 6 has a set below six. That is a miss, and the response is nothing special: same weight next time. A rough session right after a 6% jump is common.&lt;/p&gt;

&lt;p&gt;By session 8 the lifter is doing 27 reps at 42.5 kg. Reps times load has gone from 1,000 kg in session 1 to about 1,148 kg, roughly 15% more work, while the bar moved once. The load moves less often, and the reps show you are still progressing between jumps.&lt;/p&gt;

&lt;h2 id=&quot;which-add-weight-rule-should-you-use&quot;&gt;Which add-weight rule should you use?&lt;/h2&gt;

&lt;p&gt;“Every set reaches the top” is the strict version and the most common one. There are others.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Variant&lt;/th&gt;
      &lt;th&gt;Add load when&lt;/th&gt;
      &lt;th&gt;Suits&lt;/th&gt;
      &lt;th&gt;Catch&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;All sets at the top&lt;/td&gt;
      &lt;td&gt;Every working set reaches the top of the range&lt;/td&gt;
      &lt;td&gt;Most lifts; the safe default&lt;/td&gt;
      &lt;td&gt;Slowest of the single-session rules. One tired last set holds the lift back&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Two sessions in a row&lt;/td&gt;
      &lt;td&gt;All sets reach the top in two consecutive sessions&lt;/td&gt;
      &lt;td&gt;Lifts where one good day can be luck&lt;/td&gt;
      &lt;td&gt;Slower again. Worth it mainly on lifts close to your ceiling&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Rep total&lt;/td&gt;
      &lt;td&gt;The session total reaches a target, say 27 across 3 × 6-10&lt;/td&gt;
      &lt;td&gt;Lifts where the last set always lags&lt;/td&gt;
      &lt;td&gt;Lets one set drift low while the others carry it&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Top set only&lt;/td&gt;
      &lt;td&gt;The first, heaviest set reaches the top&lt;/td&gt;
      &lt;td&gt;A top set followed by lighter back-off sets&lt;/td&gt;
      &lt;td&gt;Moves load fast; the back-off sets need their own rule&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Pick one per lift and keep it for the block. Switching rules midway is how a lift ends up at a weight no rule would have chosen.&lt;/p&gt;

&lt;h2 id=&quot;why-does-adding-reps-count-as-progress&quot;&gt;Why does adding reps count as progress?&lt;/h2&gt;

&lt;p&gt;Because, over a couple of months at least, it seems to work about as well as adding load. In &lt;a href=&quot;https://peerj.com/articles/14142/&quot;&gt;Plotkin et al. (2022)&lt;/a&gt;, 38 trained lifters did eight weeks of lower-body training. One group added load and kept its reps in a range; the other kept its load and added reps. Squat strength rose 21.8 kg in the load group and 19.3 kg in the reps group, a gap the authors called of questionable practical significance, and muscle thickness changes were similar.&lt;/p&gt;

&lt;p&gt;The wider rep-range research points the same way. A &lt;a href=&quot;https://pubmed.ncbi.nlm.nih.gov/28834797/&quot;&gt;2017 meta-analysis led by Brad Schoenfeld&lt;/a&gt; found similar muscle growth with light and heavy loads when sets were taken to failure, while one-rep max strength favoured heavier loads. A &lt;a href=&quot;https://pubmed.ncbi.nlm.nih.gov/33671664/&quot;&gt;2021 re-examination of the repetition continuum&lt;/a&gt;, also led by Schoenfeld, argued that adaptations happen across a wide range of loading zones. The ACSM’s 2026 update, an overview of 137 systematic reviews, found hypertrophy did not differ across 30-100% of one-rep max when effort was comparable, and that strength gains were greater at 80% and above (&lt;a href=&quot;https://pmc.ncbi.nlm.nih.gov/articles/PMC12965823/&quot;&gt;Currier et al., 2026&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;So no rep range is magic. For size, pick a range you will push honestly. For a lift where top-end strength is the point, keep the range near the heavy end, where the strength benefit shows up.&lt;/p&gt;

&lt;h2 id=&quot;how-wide-should-the-rep-range-be&quot;&gt;How wide should the rep range be?&lt;/h2&gt;

&lt;p&gt;Wide enough that one load jump does not throw you below the bottom of it.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Range&lt;/th&gt;
      &lt;th&gt;Typical use&lt;/th&gt;
      &lt;th&gt;What to watch&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;3-5&lt;/td&gt;
      &lt;td&gt;Main barbell lifts, strength focus&lt;/td&gt;
      &lt;td&gt;Narrow. One standard jump can eat the whole range, so microload&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;6-10&lt;/td&gt;
      &lt;td&gt;Compound lifts, mixed goals&lt;/td&gt;
      &lt;td&gt;Room for a 4-6% jump to cost two or three reps&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;8-12&lt;/td&gt;
      &lt;td&gt;Most machines, dumbbells, general size work&lt;/td&gt;
      &lt;td&gt;The zone ACSM’s 2009 stand used as its example&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;12-20&lt;/td&gt;
      &lt;td&gt;Small-muscle isolation: raises, curls, calves&lt;/td&gt;
      &lt;td&gt;The next dumbbell is often a 15-25% jump, and the range has to absorb it&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;If you add weight and land below the bottom of the range two or three sessions running, the range is too narrow for the jump. Widen it, or make the jump smaller.&lt;/p&gt;

&lt;h2 id=&quot;what-is-microloading-and-when-do-you-need-it&quot;&gt;What is microloading, and when do you need it?&lt;/h2&gt;

&lt;p&gt;Microloading means adding less than the standard 2.5 kg (5 lb) step, with fractional plates from 0.25 to 1.25 kg or small add-on weights for dumbbells. The case for it is arithmetic. The same plate is a very different jump on different lifts:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Working weight&lt;/th&gt;
      &lt;th&gt;+0.5 kg&lt;/th&gt;
      &lt;th&gt;+1 kg&lt;/th&gt;
      &lt;th&gt;+2.5 kg&lt;/th&gt;
      &lt;th&gt;+5 kg&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;30 kg overhead press&lt;/td&gt;
      &lt;td&gt;1.7%&lt;/td&gt;
      &lt;td&gt;3.3%&lt;/td&gt;
      &lt;td&gt;8.3%&lt;/td&gt;
      &lt;td&gt;16.7%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;60 kg bench press&lt;/td&gt;
      &lt;td&gt;0.8%&lt;/td&gt;
      &lt;td&gt;1.7%&lt;/td&gt;
      &lt;td&gt;4.2%&lt;/td&gt;
      &lt;td&gt;8.3%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;100 kg squat&lt;/td&gt;
      &lt;td&gt;0.5%&lt;/td&gt;
      &lt;td&gt;1.0%&lt;/td&gt;
      &lt;td&gt;2.5%&lt;/td&gt;
      &lt;td&gt;5.0%&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Against ACSM’s 2-10% band, which asks for the low end on small-muscle exercises, 2.5 kg on a 30 kg press sits near the top of a range meant for big lifts. The same plate on a 100 kg squat is near the bottom. That is a large part of why the press stalls first.&lt;/p&gt;

&lt;p&gt;Dumbbells are harder, because the rack decides the jump. Going from a 10 kg to a 12 kg dumbbell for lateral raises adds 20%. Without add-on plates the practical fix is a wider range, such as 12-20, so the reps can absorb the jump.&lt;/p&gt;

&lt;p&gt;You need microloading when the smallest standard jump keeps knocking you out of the range: overhead presses, bench press for lighter lifters, most single-joint lifts. You can usually skip it on squats and deadlifts until the weights are well past bodyweight.&lt;/p&gt;

&lt;h2 id=&quot;when-does-double-progression-stop-working&quot;&gt;When does double progression stop working?&lt;/h2&gt;

&lt;p&gt;On accessories it may never need replacing. On main lifts, these are the signs I would look for before changing:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Reps flat at the same weight for three or four weeks&lt;/strong&gt;, on more than one lift at once. One stuck lift is a problem with that lift. Several at once is usually recovery, food or sleep, and no progression model fixes those.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Every jump lands you below the range&lt;/strong&gt;, even after microloading. The lift may need a heavier, narrower range for a while, or a different variation.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;You want to peak a main lift.&lt;/strong&gt; Double progression is good at building and has no plan for a heavy single on a set date. A percentage cycle off a training max, such as 5/3/1, does, starting from a one-rep max that is &lt;a href=&quot;/journal/how-to-estimate-your-one-rep-max/&quot;&gt;tested or estimated&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Before giving up on the model, change one thing inside it: swap the exercise variation, move the range (from 6-10 to 10-15 for a block), or add a set. If one lift does move to a percentage cycle, the others can keep running double progression. Mixing models across lifts is normal.&lt;/p&gt;

&lt;p&gt;This is training information, not medical advice. If a load jump hurts rather than just feels hard, have a clinician or a coach who can watch you lift take a look.&lt;/p&gt;

&lt;h2 id=&quot;how-liftlog-runs-it&quot;&gt;How LiftLog runs it&lt;/h2&gt;

&lt;p&gt;In &lt;a href=&quot;/apps/liftlog/&quot;&gt;LiftLog&lt;/a&gt;, progression is a setting on each exercise in a program rather than on the program as a whole. The choices are double progression, linear, a percentage of a training max, RPE-based, or off. Nearly nine in ten exercise rows in the bundled example programs use double progression.&lt;/p&gt;

&lt;p&gt;The rule is the strict variant from the table above. You set the target sets and a rep range, and the weight goes up only when every target set reaches the top of the range. A session inside the range holds the weight. A session where fewer than the target number of sets reach the bottom counts as a miss, and after three misses in a row the weight drops to 90% and the climb restarts. The increment, the number of misses and the drop are all editable per exercise.&lt;/p&gt;

&lt;p&gt;When a workout ends, the recap labels each exercise Progressed, Hold, Missed or Deload and shows the next session’s weight and reps, and the program list previews that next target under each exercise. Bodyweight exercises get a reps-only mode that adds one rep at a time.&lt;/p&gt;

&lt;p&gt;For microloading, the increment and the rounding step can both be set in 0.5 kg steps. Change both. With a 1 kg increment and rounding left at 2.5 kg, the next weight rounds back to where it was. The built-in plate calculator assumes a standard plate set down to 1.25 kg, so fractional plates are still your own bookkeeping.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>Shogi openings for beginners: Static Rook, Ranging Rook and the first lines to learn</title>
    <link href="https://lagerland-apps.github.io/journal/shogi-openings-for-beginners/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/shogi-openings-for-beginners/</id>
    <published>2026-08-29T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">A chess player can learn a few first moves and get by. Shogi asks a bigger question first: where is your rook going to live? Every shogi opening answers it one of two ways, and the answer decides your castle, your attack and the kind of game you will play. This post maps the openings, writes out two lines move by move, and suggests how to pick your first one.</summary>
    <content type="html">&lt;p&gt;Every shogi opening starts with one decision: does your rook stay where it started, or does it move across the board? Shogi players call the two answers &lt;strong&gt;Static Rook&lt;/strong&gt; (居飛車, &lt;em&gt;ibisha&lt;/em&gt;) and &lt;strong&gt;Ranging Rook&lt;/strong&gt; (振り飛車, &lt;em&gt;furibisha&lt;/em&gt;), and nearly every named opening belongs to one of them. Once you know which family you are in, you know roughly where your king will castle and which file your attack will come down.&lt;/p&gt;

&lt;p&gt;Moves below are in English (Hodges) notation, so P-7f is a pawn moving to 7f and Bx8h+ is a bishop capturing on 8h and promoting. If that is new, &lt;a href=&quot;/journal/making-shogi-readable-without-kanji/&quot;&gt;the piece and notation guide&lt;/a&gt; explains it in five minutes. Black (&lt;em&gt;sente&lt;/em&gt;) moves first.&lt;/p&gt;

&lt;h2 id=&quot;static-rook-or-ranging-rook&quot;&gt;Static Rook or Ranging Rook&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; &lt;/th&gt;
      &lt;th&gt;Static Rook (居飛車, ibisha)&lt;/th&gt;
      &lt;th&gt;Ranging Rook (振り飛車, furibisha)&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Where the rook goes&lt;/td&gt;
      &lt;td&gt;Stays on its starting file: 2h for Black, 8b for Gote&lt;/td&gt;
      &lt;td&gt;Moves to the 5th, 6th, 7th or 8th file (for Black)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Where the king castles&lt;/td&gt;
      &lt;td&gt;On the left, away from the rook&lt;/td&gt;
      &lt;td&gt;On the right, where the rook started&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Usual castles&lt;/td&gt;
      &lt;td&gt;Yagura, Boat, Left Mino, Static Rook Anaguma&lt;/td&gt;
      &lt;td&gt;Mino, High Mino, Silver Crown, Ranging Rook Anaguma&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;How the game usually goes&lt;/td&gt;
      &lt;td&gt;Attacks first, up the file the rook already stands on&lt;/td&gt;
      &lt;td&gt;Castles quickly, lets the opponent commit, counterattacks&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Main openings&lt;/td&gt;
      &lt;td&gt;Yagura, Bishop Exchange, Side Pawn Capture, Double Wing Attack&lt;/td&gt;
      &lt;td&gt;Central Rook, Fourth File Rook, Third File Rook, Opposing Rook&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Each player chooses separately, so there are three kinds of game: Double Static Rook, Static Rook against Ranging Rook, and Double Ranging Rook (&lt;a href=&quot;https://en.wikipedia.org/wiki/Shogi_opening&quot;&gt;Wikipedia’s overview of shogi openings&lt;/a&gt; traces how the balance between them has shifted since the Edo period). The rule underneath both families is the same: keep the king away from the rook, because the rook’s file is where the fighting starts.&lt;/p&gt;

&lt;h2 id=&quot;the-main-openings-at-a-glance&quot;&gt;The main openings at a glance&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Opening&lt;/th&gt;
      &lt;th&gt;Japanese&lt;/th&gt;
      &lt;th&gt;Family&lt;/th&gt;
      &lt;th&gt;What defines it&lt;/th&gt;
      &lt;th&gt;Usual castle&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Yagura (Fortress)&lt;/td&gt;
      &lt;td&gt;矢倉&lt;/td&gt;
      &lt;td&gt;Double Static Rook&lt;/td&gt;
      &lt;td&gt;S-7g closes the bishop diagonal; a slow build on both sides&lt;/td&gt;
      &lt;td&gt;Yagura: king 8h, silver 7g, golds 7h and 6g&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Bishop Exchange&lt;/td&gt;
      &lt;td&gt;角換わり, kakugawari&lt;/td&gt;
      &lt;td&gt;Double Static Rook&lt;/td&gt;
      &lt;td&gt;Bishops traded in the first moves, then held in hand&lt;/td&gt;
      &lt;td&gt;King walks to 7i, behind the 7h gold and 8h silver&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Side Pawn Capture&lt;/td&gt;
      &lt;td&gt;横歩取り, yokofudori&lt;/td&gt;
      &lt;td&gt;Double Static Rook&lt;/td&gt;
      &lt;td&gt;After both rook pawns are exchanged, Black’s rook takes the pawn on 3d&lt;/td&gt;
      &lt;td&gt;Varies&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Double Wing Attack&lt;/td&gt;
      &lt;td&gt;相掛かり, aigakari&lt;/td&gt;
      &lt;td&gt;Double Static Rook&lt;/td&gt;
      &lt;td&gt;Both sides push and exchange their rook pawns early&lt;/td&gt;
      &lt;td&gt;Varies&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Central Rook&lt;/td&gt;
      &lt;td&gt;中飛車, nakabisha&lt;/td&gt;
      &lt;td&gt;Ranging Rook&lt;/td&gt;
      &lt;td&gt;R-5h (R-5b for Gote)&lt;/td&gt;
      &lt;td&gt;Mino&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Fourth File Rook&lt;/td&gt;
      &lt;td&gt;四間飛車, shikenbisha&lt;/td&gt;
      &lt;td&gt;Ranging Rook&lt;/td&gt;
      &lt;td&gt;R-6h (R-4b for Gote)&lt;/td&gt;
      &lt;td&gt;Mino&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Third File Rook&lt;/td&gt;
      &lt;td&gt;三間飛車, sangenbisha&lt;/td&gt;
      &lt;td&gt;Ranging Rook&lt;/td&gt;
      &lt;td&gt;R-7h (R-3b for Gote)&lt;/td&gt;
      &lt;td&gt;Mino&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Opposing Rook&lt;/td&gt;
      &lt;td&gt;向かい飛車, mukaibisha&lt;/td&gt;
      &lt;td&gt;Ranging Rook&lt;/td&gt;
      &lt;td&gt;R-8h, facing the opponent’s rook (R-2b for Gote)&lt;/td&gt;
      &lt;td&gt;Mino&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The Ranging Rook names count files from Gote’s side, which is why Black’s Fourth File Rook sits on the sixth file (&lt;a href=&quot;https://en.wikipedia.org/wiki/Ranging_Rook&quot;&gt;Wikipedia’s Ranging Rook page&lt;/a&gt; has the full list). You will also meet two names early that are attacking methods, not openings. &lt;strong&gt;Climbing Silver&lt;/strong&gt; (棒銀, &lt;em&gt;bōgin&lt;/em&gt;) walks the right silver up the rook’s file, S-3h, S-2g, S-2f, S-2e, to support a break on the second file. &lt;strong&gt;Right Fourth File Rook&lt;/strong&gt; (右四間飛車) moves the rook to 4h to hit the opponent’s fourth file, and still counts as Static Rook.&lt;/p&gt;

&lt;h2 id=&quot;two-lines-move-by-move&quot;&gt;Two lines, move by move&lt;/h2&gt;

&lt;h3 id=&quot;fourth-file-rook-into-a-mino-castle&quot;&gt;Fourth File Rook into a Mino castle&lt;/h3&gt;

&lt;p&gt;Black plays Ranging Rook from move one:&lt;/p&gt;

&lt;p&gt;1. P-7f P-8d 2. P-6f P-8e 3. B-7g P-3d 4. R-6h S-6b 5. K-4h K-4b 6. K-3h K-3b 7. K-2h P-6d 8. S-3h G6a-5b 9. P-6e Px6e 10. Rx6e S-6c 11. G6i-5h&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;3. B-7g&lt;/strong&gt; comes before the king walks. Gote’s rook pawn on 8e wants P-8f, and from 7g the bishop covers 8f, so that exchange never works. Walk the king first and P-8f opens the eighth file straight into your camp.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;4. R-6h&lt;/strong&gt; puts the rook behind the pawn on 6f. From here rook and pawn work as one unit: every quiet move that follows prepares P-6e.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;5 to 8.&lt;/strong&gt; The king walks to 2h and the right silver steps to 3h. King 2h, silver 3h, golds 4i and 5h is the &lt;a href=&quot;https://en.wikipedia.org/wiki/Mino_castle&quot;&gt;Mino castle&lt;/a&gt;, and it is nearly finished before the first exchange.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;9. P-6e&lt;/strong&gt; is the break the whole setup prepares. If Gote does not take, Px6d wins a pawn; after Px6e Rx6e the rook stands on the fifth rank with a pawn in hand.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;11. G6i-5h&lt;/strong&gt; completes the Mino.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The plan fits in one sentence: castle on the right, then open the file your rook is standing on.&lt;/p&gt;

&lt;h3 id=&quot;the-bishop-exchange&quot;&gt;The Bishop Exchange&lt;/h3&gt;

&lt;p&gt;1. P-7f P-8d 2. G-7h P-3d 3. P-2f G-3b 4. P-2e Bx8h+ 5. Sx8h S-2b 6. S-3h S-7b 7. P-4f P-6d 8. K-6h K-4b&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;2. G-7h&lt;/strong&gt; before anything else. The gold defends 8h, so the silver can recapture there.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;4… Bx8h+&lt;/strong&gt; is the exchange. Gote takes first so that Black has to spend a move recapturing.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;5. Sx8h&lt;/strong&gt; recaptures with the silver, not the gold. Both sides now hold a bishop in hand, and a bishop dropped into a gap in your camp can fork two pieces at once.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;6. S-3h&lt;/strong&gt; is the silver every Bishop Exchange plan depends on. It climbs to 2f (Climbing Silver), rushes to 4f (Rushing Silver) or settles on 5f (Reclining Silver), as set out on &lt;a href=&quot;https://en.wikipedia.org/wiki/Bishop_Exchange&quot;&gt;Wikipedia’s Bishop Exchange page&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;8. K-6h&lt;/strong&gt; starts the king’s walk to safety, because with a bishop in each hand a king left in the open is the first target.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;which-opening-should-you-learn-first&quot;&gt;Which opening should you learn first?&lt;/h2&gt;

&lt;p&gt;Pick one family and stay with it until you know its castle and its main attack without thinking. Switching openings every game means you never get past move ten in any of them.&lt;/p&gt;

&lt;p&gt;If you like to build first and hit back later, Fourth File Rook has one of the shortest plans to learn: the line above is the whole idea, and the Mino castle takes only a handful of moves. If you would rather attack, play Static Rook with Climbing Silver. One silver and one file give you a plan you can start on move one, and it teaches the pawn exchanges and drops on the second file that come up in most Static Rook openings.&lt;/p&gt;

&lt;p&gt;Leave Side Pawn Capture and the deep Bishop Exchange lines for later. Both turn sharp early, with pieces in hand on both sides, so one missed drop can decide the game. That kind of mistake shows up clearly in an engine review, as &lt;a href=&quot;/journal/reading-a-shogi-engine-evaluation/&quot;&gt;the post on reading a shogi engine evaluation&lt;/a&gt; explains, but it is easier to avoid while you are still learning how a castle holds together.&lt;/p&gt;

&lt;h2 id=&quot;how-shogiful-teaches-openings&quot;&gt;How Shogiful teaches openings&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/apps/shogiful/&quot;&gt;Shogiful&lt;/a&gt; splits opening study into three parts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Openings lesson track&lt;/strong&gt; has ten lessons. It starts with “Choosing your rook” and covers Static Rook basics, the Ranging Rook families, Fourth File, Central, Third File and Opposing Rook, Climbing Silver and the Bishop Exchange. It ends with “Choosing your opening”, which gives the same advice as above: one family, its castle and its main attack.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Joseki Lab&lt;/strong&gt; has 55 opening lines in 11 families: Static Rook, Ranging Rook, Fourth File Rook, Third File Rook, Central Rook, Side Pawn Capture, Bishop Exchange, Yagura, Right Fourth File, Anaguma Openings and Double Static Rook. You play your own side’s moves and the opponent’s replies are played for you. Short notes appear at the moments that matter, under “What just happened”. If you play a known sideline, the drill explains how it is punished instead of just marking it wrong. Where the opponent has a second main defence, a card shows it to you. Lines you miss come back sooner through spaced repetition. The two lines above are Joseki Lab lines, and the move notes are condensed from their commentary.&lt;/p&gt;

&lt;p&gt;The lines did not always go that far. Until early August, 38 of the 55 contained no capture at all. Each one built the formation and stopped exactly where the real game starts, so the Climbing Silver line ended the moment the silver reached 2f. A two-star App Store review pointed it out before any test did. Every line now plays through the first exchange of pieces, and each family shows two defences in full.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Castle Atelier&lt;/strong&gt; drills twelve castles, from Mino and Yagura to both Anagumas. You build them, break into them, and repair them after an intrusion. After each analysed game, Game Review shows a badge naming the castle you actually built. YaneuraOu runs the analysis on your device, so there is no account and no server.&lt;/p&gt;

&lt;p&gt;Shogiful is free to download, with Premium from $1.99 a month, $9.99 a year or $19.99 once. If you would rather try openings against people, the online platforms such as &lt;a href=&quot;/alternatives/lishogi/&quot;&gt;Lishogi&lt;/a&gt; and &lt;a href=&quot;/alternatives/81dojo/&quot;&gt;81Dojo&lt;/a&gt; are built for that, and &lt;a href=&quot;/guides/best-shogi-apps-iphone/&quot;&gt;the guide to shogi apps for iPhone&lt;/a&gt; covers the rest of the field.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>Puppy and kitten vaccination schedules: what&apos;s due when, and which dates to keep</title>
    <link href="https://lagerland-apps.github.io/journal/puppy-and-kitten-vaccination-schedule/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/puppy-and-kitten-vaccination-schedule/</id>
    <published>2026-08-22T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Most puppies and kittens get their first vaccines at six to eight weeks. What comes after is where owners lose track: how many more doses, how far apart, why the last one has to wait until 16 weeks, and why the vet wants another visit at six months or a year. Three sets of veterinary guidelines answer those questions and mostly agree. Below they are side by side, along with the dates worth keeping from every certificate.</summary>
    <content type="html">&lt;p&gt;There are three sets of guidelines behind almost every small-animal vaccination schedule: the &lt;a href=&quot;https://www.aaha.org/globalassets/02-guidelines/2022-aaha-canine-vaccination-guidelines/resources/2022-aaha-canine-vaccinations-guidelines.pdf&quot;&gt;AAHA canine guidelines&lt;/a&gt; (2022, updated in 2024), the &lt;a href=&quot;https://www.aaha.org/globalassets/02-guidelines/feline-vaccination-guidlines/resource-center/2020-aahaa-afp-feline-vaccination-guidelines.pdf&quot;&gt;AAHA/AAFP feline guidelines&lt;/a&gt; (2020), both written for North America, and the &lt;a href=&quot;https://wsava.org/wp-content/uploads/2024/05/2024-Guidelines-for-the-Vaccination-of-Dogs-and-Cats.pdf&quot;&gt;WSAVA guidelines&lt;/a&gt; (2024), written for vets worldwide. They are guidance for vets, not a calendar to follow without one. Your vet adjusts for the animal, the products in stock and local disease, and rabies is set by law. The tables below are what the guidelines say.&lt;/p&gt;

&lt;h2 id=&quot;puppy-vaccination-schedule&quot;&gt;Puppy vaccination schedule&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Age&lt;/th&gt;
      &lt;th&gt;Core: distemper, adenovirus, parvovirus (often with parainfluenza)&lt;/th&gt;
      &lt;th&gt;Leptospirosis&lt;/th&gt;
      &lt;th&gt;Rabies&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;6 to 8 weeks&lt;/td&gt;
      &lt;td&gt;First dose&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Then every 2 to 4 weeks&lt;/td&gt;
      &lt;td&gt;Repeat&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;From 12 weeks&lt;/td&gt;
      &lt;td&gt;Series continues&lt;/td&gt;
      &lt;td&gt;First dose&lt;/td&gt;
      &lt;td&gt;US products labelled from 3 months; timing set by law&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2 to 4 weeks later&lt;/td&gt;
      &lt;td&gt;Series continues&lt;/td&gt;
      &lt;td&gt;Second dose&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;16 weeks or older&lt;/td&gt;
      &lt;td&gt;Final dose of the series&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;About 6 months&lt;/td&gt;
      &lt;td&gt;WSAVA: booster at or after 26 weeks&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Within a year of the series&lt;/td&gt;
      &lt;td&gt;AAHA: one booster&lt;/td&gt;
      &lt;td&gt;One booster&lt;/td&gt;
      &lt;td&gt;Booster 1 year after the first dose&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;After that&lt;/td&gt;
      &lt;td&gt;Every 3 years&lt;/td&gt;
      &lt;td&gt;Every year&lt;/td&gt;
      &lt;td&gt;Every 1 or 3 years, by product and law&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;AAHA’s table asks for at least three core doses between 6 and 16 weeks, 2 to 4 weeks apart, and its text recommends repeating them until the puppy is older than 16 weeks, with 18 to 20 weeks preferred where distemper or parvovirus risk is high. A puppy that starts at 8 weeks on a 4-week interval gets core doses at 8, 12 and 16 weeks; one that starts at 6 weeks on a 3-week interval needs five visits to reach 16.&lt;/p&gt;

&lt;p&gt;Leptospirosis changed category recently. The 2022 AAHA guidelines listed it as non-core, while noting that some task force members wanted it core. In June 2024 AAHA &lt;a href=&quot;https://www.aaha.org/newstat/publications/leptospirosis-vaccination-recommended-to-be-core-for-most-dogs/&quot;&gt;moved it to core&lt;/a&gt;, and WSAVA’s 2024 guidelines call it core wherever the disease is endemic, the relevant serogroups are known and suitable vaccines exist. Leptospirosis vaccines are killed bacterins that protect for about 12 to 18 months, so AAHA keeps them annual.&lt;/p&gt;

&lt;h2 id=&quot;kitten-vaccination-schedule&quot;&gt;Kitten vaccination schedule&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Age&lt;/th&gt;
      &lt;th&gt;FVRCP: panleukopenia, herpesvirus-1, calicivirus&lt;/th&gt;
      &lt;th&gt;FeLV (core under 1 year)&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;From 6 weeks&lt;/td&gt;
      &lt;td&gt;First dose&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Then every 3 to 4 weeks&lt;/td&gt;
      &lt;td&gt;Repeat until 16 to 20 weeks&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;From 8 weeks&lt;/td&gt;
      &lt;td&gt;Series continues&lt;/td&gt;
      &lt;td&gt;First dose&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;3 to 4 weeks later&lt;/td&gt;
      &lt;td&gt;Series continues&lt;/td&gt;
      &lt;td&gt;Second dose&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;6 months&lt;/td&gt;
      &lt;td&gt;Revaccinate&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;First annual visit&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;Booster&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;After that&lt;/td&gt;
      &lt;td&gt;Every 3 years (injectable), yearly (intranasal)&lt;/td&gt;
      &lt;td&gt;Non-core after age 1: yearly if contact with FeLV-positive cats is likely, every 2 to 3 years if less likely&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;That is the &lt;a href=&quot;https://aaha.org/wp-content/uploads/globalassets/02-guidelines/feline-vaccination-guidlines/feline-vaccine-table.pdf&quot;&gt;AAHA/AAFP schedule for general practice&lt;/a&gt;. Rabies sits outside the grid: it is given as the law requires, with a booster at the first annual visit, and the AAHA/AAFP guidelines count it as core for cats even where the law does not require it. WSAVA’s kitten schedule is close: doses every 2 to 4 weeks, the last at 16 weeks or older, and revaccination at or after 26 weeks.&lt;/p&gt;

&lt;h2 id=&quot;why-the-last-dose-has-to-wait-until-16-weeks&quot;&gt;Why the last dose has to wait until 16 weeks&lt;/h2&gt;

&lt;p&gt;Puppies and kittens get antibodies from their mother, and those maternal antibodies block vaccines as well as infections. They fade at different rates in different animals, even within a litter, and there is no way to predict when a particular kitten’s or puppy’s have gone. AAHA notes that maternal antibodies against parvovirus may last 13 to 15 weeks or longer. The series is a way of making sure one dose lands after they fade, which is why the final dose matters more than the number of doses. WSAVA puts it bluntly: if a puppy or kitten can only have one vaccination, for example because of cost, it should be the core vaccines at 16 weeks or older.&lt;/p&gt;

&lt;p&gt;The 6-month booster closes the remaining gap. The AAHA/AAFP guidelines cite studies suggesting that up to a third of kittens may not respond to a final dose at 16 weeks and may still carry blocking antibodies at 20 weeks. WSAVA now advises revaccinating puppies and kittens at or after 26 weeks rather than waiting until 12 to 16 months.&lt;/p&gt;

&lt;h2 id=&quot;adult-boosters-every-three-years-or-every-year&quot;&gt;Adult boosters: every three years, or every year?&lt;/h2&gt;

&lt;p&gt;It depends on the vaccine. AAHA recommends core dog boosters every 3 years after the first-year booster and says annual core boosters are not necessary. WSAVA’s position is that core vaccines should be given no more often than necessary, because modern modified-live core vaccines protect for many years, while most non-core vaccines protect for about one. So a typical adult dog has a core booster every third year and some vaccines every year:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Leptospirosis:&lt;/strong&gt; yearly.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Kennel cough (Bordetella with parainfluenza):&lt;/strong&gt; a single intranasal dose for dogs at risk, then yearly. AAHA notes that dogs at high risk may benefit from a dose more often than that, for example before boarding.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Lyme disease:&lt;/strong&gt; for dogs that live in or travel to areas where it occurs. Two doses 2 to 4 weeks apart, finished 2 to 4 weeks before travel, then yearly.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Canine influenza:&lt;/strong&gt; two doses 2 to 4 weeks apart, a booster within a year, then yearly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;WSAVA also asks vets to treat the yearly visit as a health check rather than a vaccination appointment, so that visit doesn’t go away when the core shots stop being annual.&lt;/p&gt;

&lt;h2 id=&quot;what-to-copy-from-every-vaccination-certificate&quot;&gt;What to copy from every vaccination certificate&lt;/h2&gt;

&lt;p&gt;A vaccination certificate settles questions that memory can’t. For each vaccine, keep:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;The vaccine as written,&lt;/strong&gt; product name included. “Rabies, 3-year” and “rabies, 1-year” are different due dates.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The date given.&lt;/strong&gt; For a puppy or kitten, check it against the date of birth: the last dose of the series should fall at 16 weeks or later.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The next due date,&lt;/strong&gt; copied from the certificate rather than worked out yourself, since products and local rules differ.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The lot or batch number,&lt;/strong&gt; which identifies the exact vial if a reaction ever needs reporting. WSAVA encourages vets to report every possible adverse event to the manufacturer and the regulator.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The clinic and the vet&lt;/strong&gt; who gave it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Keep the certificates themselves, not just notes of them, especially for rabies. Kennels and groomers usually want proof of vaccination, and some want it given a set number of days before arrival; the post on &lt;a href=&quot;/journal/pet-medical-records-what-to-keep/&quot;&gt;what belongs in a pet’s medical record&lt;/a&gt; covers who asks for what.&lt;/p&gt;

&lt;h2 id=&quot;where-pawza-fits&quot;&gt;Where Pawza fits&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/apps/pawza/&quot;&gt;Pawza&lt;/a&gt; is a pet health record app for iPhone and iPad. It does not contain a vaccination schedule and does not decide what your pet needs; the dates come from your vet’s paperwork, so it works with any vet’s protocol and any country’s rabies rules. It keeps those dates and tells you when one comes up.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Scanning a certificate.&lt;/strong&gt; Pawza reads the page on the device. The review screen lists each vaccine with its name, the date administered, the next due date and an optional lot number, and nothing is saved until you have checked them. With Pawza Pro on an iPhone or iPad with Apple Intelligence (iOS 26 or later) the fields fill in automatically; otherwise you fill them in from the recognised text.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;A reminder for the printed due date.&lt;/strong&gt; If the certificate gives a next due date, Pawza offers to add a vaccination reminder for that day.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Adding one by hand.&lt;/strong&gt; Logging a vaccination record by hand offers the same reminder, set one year from the date given.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Given the schedules above, note that both of those reminders repeat yearly by default. That is right for leptospirosis or kennel cough. It is wrong for a puppy or kitten series 2 to 4 weeks apart and for a 3-year booster. Open the reminder, set the date your vet gave you, and change Repeats to Never; add one reminder per dose for a series. A reminder fires on the date you set, so if a kennel wants boosters given some days before arrival, set it earlier. You can mark a reminder time-sensitive so it breaks through Focus, and the list sorts everything into overdue, today, this week and later.&lt;/p&gt;

&lt;p&gt;With Pro, the vet-visit PDF lists every vaccination with its last date and next due date, on pages you can hand to a new clinic or a boarding kennel. The free version covers one pet. There is no Pawza account and no Pawza server: records stay on your device, with optional sync through your own iCloud. The reasons are in &lt;a href=&quot;/journal/vet-paperwork-stays-on-your-phone/&quot;&gt;why vet paperwork should stay on your phone&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Your vet sets the schedule. If you keep the dates from the certificates, you can answer “when was the last one?” without a phone call.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>RPE and RIR explained: the 1-10 effort scale for lifting and how to rate a set honestly</title>
    <link href="https://lagerland-apps.github.io/journal/rpe-and-rir-explained/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/rpe-and-rir-explained/</id>
    <published>2026-08-17T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Two lifters can both do 3 sets of 5 at 100 kg and be having completely different workouts. One finished every set with three reps to spare; the other ground out the last rep of each. RPE and RIR are the two ways lifters write that difference down. They count the same thing from opposite ends, and the scale most people use comes from one specific study.</summary>
    <content type="html">&lt;p&gt;RPE and RIR describe the same thing: how close a set came to the point where you could not do another good rep.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;RIR (reps in reserve)&lt;/strong&gt; counts what was left. Two reps in reserve means you stopped two short of failure.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;RPE (rating of perceived exertion)&lt;/strong&gt; scores how hard it was on a 1-10 scale, where 10 is nothing left.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the usual working range, RPE = 10 − RIR. Most of the remaining detail concerns the ends of the scale.&lt;/p&gt;

&lt;h2 id=&quot;what-does-each-rpe-number-mean&quot;&gt;What does each RPE number mean?&lt;/h2&gt;

&lt;p&gt;This is the resistance-training scale published by &lt;a href=&quot;https://pubmed.ncbi.nlm.nih.gov/26049792/&quot;&gt;Zourdos and colleagues in 2016&lt;/a&gt;. When a program today writes RPE 8 next to a set, this is usually the scale it means.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;RPE&lt;/th&gt;
      &lt;th&gt;Description&lt;/th&gt;
      &lt;th&gt;Reps in reserve&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;10&lt;/td&gt;
      &lt;td&gt;Maximum effort&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;9.5&lt;/td&gt;
      &lt;td&gt;No further reps, but could increase load&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;9&lt;/td&gt;
      &lt;td&gt;1 rep remaining&lt;/td&gt;
      &lt;td&gt;1&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;8.5&lt;/td&gt;
      &lt;td&gt;1 or 2 reps remaining&lt;/td&gt;
      &lt;td&gt;1-2&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;8&lt;/td&gt;
      &lt;td&gt;2 reps remaining&lt;/td&gt;
      &lt;td&gt;2&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;7.5&lt;/td&gt;
      &lt;td&gt;2 or 3 reps remaining&lt;/td&gt;
      &lt;td&gt;2-3&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;7&lt;/td&gt;
      &lt;td&gt;3 reps remaining&lt;/td&gt;
      &lt;td&gt;3&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;5-6&lt;/td&gt;
      &lt;td&gt;4 to 6 reps remaining&lt;/td&gt;
      &lt;td&gt;4-6&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;3-4&lt;/td&gt;
      &lt;td&gt;Light effort&lt;/td&gt;
      &lt;td&gt;n/a&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;1-2&lt;/td&gt;
      &lt;td&gt;Little to no effort&lt;/td&gt;
      &lt;td&gt;n/a&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The subtraction breaks in two places. RPE 9.5 exists because a heavy single or double can leave you with no more reps but a sense that 2.5 kg more would still have gone up. And everything from RPE 6 down is deliberately vague, because nobody can tell the difference between five and six reps left with any confidence.&lt;/p&gt;

&lt;h2 id=&quot;where-did-the-lifting-version-of-rpe-come-from&quot;&gt;Where did the lifting version of RPE come from?&lt;/h2&gt;

&lt;p&gt;Perceived-exertion scales are decades older than strength training apps, but the generic ones ask how hard the effort &lt;em&gt;felt&lt;/em&gt;, which suits a set of squats poorly. Your legs and lungs can feel terrible on a set of 20 that still had reps left in it.&lt;/p&gt;

&lt;p&gt;Zourdos and colleagues tied the number to something you can at least try to count. In their study, 29 people (15 experienced squatters and 14 novices) worked up to a one-rep max, then did singles at 60, 75 and 90 percent of it and a set of 8 at 70 percent, rating each with the new scale while bar speed was measured. Ratings and bar speed moved strongly in opposite directions in both groups: as sets got slower, ratings went up. Experienced squatters also rated their true max higher than novices did, a hint that the top of the scale takes practice.&lt;/p&gt;

&lt;p&gt;A companion paper by &lt;a href=&quot;https://doi.org/10.1519/SSC.0000000000000218&quot;&gt;Helms and colleagues in 2016&lt;/a&gt; laid out how to use the scale in training, and a &lt;a href=&quot;https://pubmed.ncbi.nlm.nih.gov/27243918/&quot;&gt;2017 study of 15 powerlifters&lt;/a&gt; found very strong relationships between RPE and percentage of max on the squat, bench and deadlift. Even at a true one-rep max, those lifters averaged 9.6 to 9.7, short of a flat 10.&lt;/p&gt;

&lt;h2 id=&quot;how-accurate-are-lifters-at-judging-reps-in-reserve&quot;&gt;How accurate are lifters at judging reps in reserve?&lt;/h2&gt;

&lt;p&gt;On average, within about a rep, with plenty of individual variation. The best summary is &lt;a href=&quot;https://pubmed.ncbi.nlm.nih.gov/34542869/&quot;&gt;Halperin and colleagues’ 2022 meta-analysis&lt;/a&gt; in &lt;em&gt;Sports Medicine&lt;/em&gt;, which pooled 12 studies with 414 participants:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;People underpredicted the reps they had left by about 0.95 reps. In other words, they tended to stop a little further from failure than they thought.&lt;/li&gt;
  &lt;li&gt;Predictions got more accurate closer to failure. A guess made on the last rep beats one made on the third.&lt;/li&gt;
  &lt;li&gt;Sets of 12 reps or fewer were judged far more accurately than longer sets.&lt;/li&gt;
  &lt;li&gt;Later sets were slightly more accurate than early ones.&lt;/li&gt;
  &lt;li&gt;Training status didn’t seem to matter much. Experience makes you comfortable under a bar without automatically making the counting accurate.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The variation between studies was large, so treat “about one rep” as a rough figure. In practice, RPE 7 is a fuzzy number and RPE 9 a fairly sharp one.&lt;/p&gt;

&lt;h2 id=&quot;how-do-you-rate-a-set-honestly&quot;&gt;How do you rate a set honestly?&lt;/h2&gt;

&lt;p&gt;These are the rules I use, based on what the research above says goes wrong.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Rate the last rep, straight after the set. Rating the whole set, or rating after the rest period when the memory has softened, skews the number.&lt;/li&gt;
  &lt;li&gt;Ask the RIR question, then convert. With the same technique, how many more could I have done? Answer that, subtract from 10, and you have the RPE.&lt;/li&gt;
  &lt;li&gt;Count only good reps. A rep that would have needed a different bar path or a bounce is not in reserve.&lt;/li&gt;
  &lt;li&gt;Use half points only from about 7.5 up. Lower down the scale you can’t actually tell the difference.&lt;/li&gt;
  &lt;li&gt;Calibrate now and then. On a safe exercise, such as a machine or a lift set up with safety arms, predict your reps in reserve on the last set, then keep going to failure and compare. Do it on a few lifts and you learn which direction your own error runs.&lt;/li&gt;
  &lt;li&gt;Expect the same load to rate differently on different days. A short night is the classic cause, and it is the reason &lt;a href=&quot;/journal/the-strength-logger-no-one-asked-for/&quot;&gt;the original GymLogger X post&lt;/a&gt; told lifters to hold their weights the week the clocks change. A higher RPE on a bad day is useful information about recovery.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Also, don’t rate warm-ups. A warm-up rated RPE 4 tells you nothing you need.&lt;/p&gt;

&lt;h2 id=&quot;what-is-autoregulation-and-does-it-work&quot;&gt;What is autoregulation, and does it work?&lt;/h2&gt;

&lt;p&gt;Autoregulation means letting the day’s rating set the load in place of a fixed number. A typical version: work up to a top set of 3 at RPE 8, then take a planned amount off that weight for the back-off sets. On a good day the RPE 8 triple is heavier than last week; on a bad one it is lighter, and the plan still holds.&lt;/p&gt;

&lt;p&gt;The best controlled comparison I know is &lt;a href=&quot;https://pubmed.ncbi.nlm.nih.gov/29628895/&quot;&gt;Helms and colleagues’ 2018 study&lt;/a&gt;. Twenty-one trained men ran the same eight-week, three-days-a-week squat and bench program. One group set loads from percentages of a pre-tested max; the other chose loads to land in target RPE ranges. Both gained strength and muscle thickness. The difference between groups wasn’t statistically significant, and the authors’ probability analysis gave the RPE group a likely small strength advantage. It is one study with 21 people, so the fair summary is that both methods work and RPE loading is at least as good.&lt;/p&gt;

&lt;p&gt;The decision rules that sit on top of RPE (when to add load, when a falling top set means you need a lighter week) are in the progression-model table of &lt;a href=&quot;/journal/choosing-a-strength-program-you-will-finish/&quot;&gt;the program-choosing post&lt;/a&gt;. And the same idea runs through &lt;a href=&quot;/journal/how-to-estimate-your-one-rep-max/&quot;&gt;estimating your one-rep max&lt;/a&gt;: an estimate from a set at RPE 7 reads low, because the formula assumes you went close to failure.&lt;/p&gt;

&lt;h2 id=&quot;should-you-log-rpe-or-rir&quot;&gt;Should you log RPE or RIR?&lt;/h2&gt;

&lt;p&gt;They carry the same information, so pick the one you will actually record. RIR is easier to start with because it is a count. RPE is handy once you lift heavy singles and doubles, where 9.5 says something RIR can’t. If a program is written in one and you think in the other, convert with 10 − x and move on.&lt;/p&gt;

&lt;p&gt;Consistency matters more than the choice. A rating you give every hard set, the same way, builds a record of what a given RPE costs you in kilos. A rating you remember once a fortnight records little more than your mood.&lt;/p&gt;

&lt;h2 id=&quot;how-gymlogger-x-uses-reps-in-reserve&quot;&gt;How GymLogger X uses reps in reserve&lt;/h2&gt;

&lt;p&gt;In &lt;a href=&quot;/apps/gymlogger-x/&quot;&gt;GymLogger X&lt;/a&gt;, RIR is part of the prescription. When the Smart Program Creator builds a program, each exercise gets sets, a rep range and a reps-in-reserve target, and the program preview shows it alongside them, for example 3 × 8-12 at RIR 2. The targets follow a few fixed rules:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The starting point depends on the goal. Compound lifts in a hypertrophy program start at 8-12 reps with 2 in reserve; a strength program starts them at 3-6 reps with 1 in reserve; general fitness at 10-15 reps with 3.&lt;/li&gt;
  &lt;li&gt;Lifters aged 40 and over get one extra rep in reserve, and 55 and over get two.&lt;/li&gt;
  &lt;li&gt;If you tell it about an injury, movements that load that area get two or four extra reps in reserve, depending on the phase you are in.&lt;/li&gt;
  &lt;li&gt;In a linear cycle, the target tightens by up to two reps across the weeks before the deload.&lt;/li&gt;
  &lt;li&gt;Deload weeks cut the sets roughly in half and raise the reps-in-reserve target, by three in most program styles.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you import a program from a spreadsheet, the importer reads an RIR column, or an RPE column converted as 10 − RPE.&lt;/p&gt;

&lt;p&gt;What GymLogger X doesn’t do is ask you to rate each set. A logged set is the weight and the reps, entered on the iPhone or from the Apple Watch, and the strength trend, estimated maxes and plateau rule are all built from those two numbers. I would rather the app worked from what the bar did than from a rating that research says drifts by a rep. Still, if you want a per-set RPE column in your log, that is a real gap, and you should know about it before you choose.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>The bill-splitting math nobody agrees on: tax, tip, shared plates, and the leftover cent</title>
    <link href="https://lagerland-apps.github.io/journal/bill-splitting-math-tax-tip-shared-plates/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/bill-splitting-math-tax-tip-shared-plates/</id>
    <published>2026-08-13T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">There is no single correct way to split a restaurant bill. There are about six defensible ways, they produce answers that differ by twenty dollars a head, and your table has never agreed on which one it uses. Below is every rule with the arithmetic worked all the way out: tax, tip, the shared bottle, and the cent that will not divide.</summary>
    <content type="html">&lt;p&gt;Nobody at the table is confused about arithmetic. Four adults can divide $154.65 by four in their heads, near enough.&lt;/p&gt;

&lt;p&gt;The argument that follows is about something else. There are roughly six defensible rules for splitting a restaurant bill, they disagree with each other by twenty dollars a head, and no group has ever sat down and picked one in advance. So the rule gets chosen at the moment of maximum social pressure, by whoever speaks first, and the person it disadvantages says nothing.&lt;/p&gt;

&lt;p&gt;The rules are below, with the arithmetic worked all the way out. Why the fair rule is hard to propose comes after the numbers, which are the easy half.&lt;/p&gt;

&lt;h2 id=&quot;what-are-you-actually-splitting&quot;&gt;What are you actually splitting?&lt;/h2&gt;

&lt;p&gt;A restaurant bill is four or five separate things stacked on top of each other. Each layer has its own defensible rule, and most bill arguments come from applying one layer’s rule to a different layer.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Layer&lt;/th&gt;
      &lt;th&gt;What it is&lt;/th&gt;
      &lt;th&gt;The defensible rule&lt;/th&gt;
      &lt;th&gt;The common mistake&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Line items&lt;/td&gt;
      &lt;td&gt;What each person ordered&lt;/td&gt;
      &lt;td&gt;To the person who ordered it&lt;/td&gt;
      &lt;td&gt;Averaging the whole subtotal across heads&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Shared plates&lt;/td&gt;
      &lt;td&gt;Appetisers, sides, a bottle for the table&lt;/td&gt;
      &lt;td&gt;Split among the people who actually had it&lt;/td&gt;
      &lt;td&gt;Charging the whole table by headcount&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Sales tax (US)&lt;/td&gt;
      &lt;td&gt;Added on top of the printed prices&lt;/td&gt;
      &lt;td&gt;Proportional to each person’s subtotal&lt;/td&gt;
      &lt;td&gt;Splitting it by headcount, which overcharges the small order twice&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;VAT (EU/UK)&lt;/td&gt;
      &lt;td&gt;Already inside every printed price&lt;/td&gt;
      &lt;td&gt;Nothing to do; it rides along with the item&lt;/td&gt;
      &lt;td&gt;Adding it again on top of the line totals&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Tip&lt;/td&gt;
      &lt;td&gt;Discretionary; US checks often print suggestions in the 18-25% band&lt;/td&gt;
      &lt;td&gt;Proportional to each person’s subtotal&lt;/td&gt;
      &lt;td&gt;A flat amount per head, which is an even split in disguise&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Service charge&lt;/td&gt;
      &lt;td&gt;Printed on the bill, often 12.5% in the UK&lt;/td&gt;
      &lt;td&gt;Already inside the total; treat it as part of the printed line&lt;/td&gt;
      &lt;td&gt;Tipping again on top without noticing&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Two notes on that table.&lt;/p&gt;

&lt;p&gt;US sales tax is added on top, and the rate is local. New York City’s combined state and local rate is 8.875% (4% state, 4.5% city, and a 0.375% Metropolitan Commuter Transportation District surcharge), which you can check in the New York State Department of Taxation and Finance’s &lt;a href=&quot;https://www.tax.ny.gov/pdf/publications/sales/pub718.pdf&quot;&gt;Publication 718 rate tables&lt;/a&gt;. In the EU and UK, VAT is already baked into every printed price, so there is no tax layer to distribute at all. That single structural difference is why American and European bill-splitting arguments sound nothing alike: in Europe the line item is the whole truth, and in the US it is roughly three-quarters of what you will actually pay once tax and tip land on top.&lt;/p&gt;

&lt;p&gt;Whether the tip goes on the pre-tax subtotal or the post-tax total is a matter of convention. The traditional answer is pre-tax, because the tax is not the restaurant’s money. The suggested-tip lines printed at the bottom of many US checks are computed on the post-tax total. On the bill below, that is the difference between $24.00 and $26.13. Neither is wrong, as long as you say which one you used. How large the tip should be in the first place depends on the setting, and &lt;a href=&quot;/journal/how-much-to-tip-in-the-us/&quot;&gt;the US tipping guide&lt;/a&gt; has the ranges, situation by situation.&lt;/p&gt;

&lt;p&gt;The UK has a related wrinkle worth knowing: since the &lt;a href=&quot;https://www.legislation.gov.uk/ukpga/2023/13/contents&quot;&gt;Employment (Allocation of Tips) Act 2023&lt;/a&gt; came into force in October 2024, employers must pass on 100% of qualifying tips and service charges to staff. It does not change your arithmetic. It does mean the discretionary service line is now more likely to reach the people who served you than it once was.&lt;/p&gt;

&lt;h2 id=&quot;example-1-what-proportional-tax-and-tip-actually-costs-the-steak&quot;&gt;Example 1: what proportional tax and tip actually costs the steak&lt;/h2&gt;

&lt;p&gt;Four people. One ribeye at $58, one salad at $14, and two orders in between. Subtotal $120.00. Tax at 8.875% is $10.65. Tip at 20% of the pre-tax subtotal is $24.00. The bill is &lt;strong&gt;$154.65&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Each person’s tax share is (their items divided by $120) times $10.65. Their tip share is the same fraction of $24.00. So Alex’s order, which is 11.67% of the food, carries 11.67% of the tax and 11.67% of the tip.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Person&lt;/th&gt;
      &lt;th&gt;Ordered&lt;/th&gt;
      &lt;th&gt;Items&lt;/th&gt;
      &lt;th&gt;Tax share&lt;/th&gt;
      &lt;th&gt;Tip share&lt;/th&gt;
      &lt;th&gt;Pays, by item&lt;/th&gt;
      &lt;th&gt;Even split&lt;/th&gt;
      &lt;th&gt;Difference&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Dana&lt;/td&gt;
      &lt;td&gt;Ribeye&lt;/td&gt;
      &lt;td&gt;$58.00&lt;/td&gt;
      &lt;td&gt;$5.15&lt;/td&gt;
      &lt;td&gt;$11.60&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;$74.75&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;$38.66&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;+$36.09&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Ben&lt;/td&gt;
      &lt;td&gt;Pasta, beer&lt;/td&gt;
      &lt;td&gt;$28.00&lt;/td&gt;
      &lt;td&gt;$2.49&lt;/td&gt;
      &lt;td&gt;$5.60&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;$36.09&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;$38.66&lt;/td&gt;
      &lt;td&gt;-$2.57&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Cara&lt;/td&gt;
      &lt;td&gt;Burger&lt;/td&gt;
      &lt;td&gt;$20.00&lt;/td&gt;
      &lt;td&gt;$1.78&lt;/td&gt;
      &lt;td&gt;$4.00&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;$25.78&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;$38.66&lt;/td&gt;
      &lt;td&gt;-$12.88&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Alex&lt;/td&gt;
      &lt;td&gt;Salad&lt;/td&gt;
      &lt;td&gt;$14.00&lt;/td&gt;
      &lt;td&gt;$1.24&lt;/td&gt;
      &lt;td&gt;$2.80&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;$18.04&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;$38.66&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;-$20.62&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;$120.00&lt;/td&gt;
      &lt;td&gt;$10.65&lt;/td&gt;
      &lt;td&gt;$24.00&lt;/td&gt;
      &lt;td&gt;$154.66&lt;/td&gt;
      &lt;td&gt;$154.64&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Look at the last column. An even split charges Alex $20.62 more than the salad actually cost, on one dinner at a table of four. Over twenty-six dinners a year with the same group and the same ordering habits, that is $536 moving from the salad to the ribeye.&lt;/p&gt;

&lt;p&gt;Notice what the tip column does. Under an even split, Alex pays $6.00 of the tip on $14 of food. Under proportional distribution, Alex pays $2.80. The tip is where even-splitting does the damage nobody notices, because it is the layer people are least likely to check.&lt;/p&gt;

&lt;p&gt;Now look at the two totals. The by-item column sums to $154.66. The even column sums to $154.64. The receipt says $154.65. Neither is a mistake and neither can be fixed by being more careful, which is Example 3.&lt;/p&gt;

&lt;h2 id=&quot;who-pays-for-the-shared-appetiser-and-who-pays-for-the-bottle&quot;&gt;Who pays for the shared appetiser, and who pays for the bottle?&lt;/h2&gt;

&lt;p&gt;Same table, different night. Four mains, one charcuterie board at $24 in the middle of the table, one bottle of wine at $48. Sam is driving and drank water.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Person&lt;/th&gt;
      &lt;th&gt;Main&lt;/th&gt;
      &lt;th&gt;Board (÷4)&lt;/th&gt;
      &lt;th&gt;Bottle ÷4&lt;/th&gt;
      &lt;th&gt;Bottle ÷3&lt;/th&gt;
      &lt;th&gt;By headcount&lt;/th&gt;
      &lt;th&gt;By consumption&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Nora&lt;/td&gt;
      &lt;td&gt;$26&lt;/td&gt;
      &lt;td&gt;$6&lt;/td&gt;
      &lt;td&gt;$12&lt;/td&gt;
      &lt;td&gt;$16&lt;/td&gt;
      &lt;td&gt;$44&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;$48&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Ivan&lt;/td&gt;
      &lt;td&gt;$32&lt;/td&gt;
      &lt;td&gt;$6&lt;/td&gt;
      &lt;td&gt;$12&lt;/td&gt;
      &lt;td&gt;$16&lt;/td&gt;
      &lt;td&gt;$50&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;$54&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Priya&lt;/td&gt;
      &lt;td&gt;$22&lt;/td&gt;
      &lt;td&gt;$6&lt;/td&gt;
      &lt;td&gt;$12&lt;/td&gt;
      &lt;td&gt;$16&lt;/td&gt;
      &lt;td&gt;$40&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;$44&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Sam (no wine)&lt;/td&gt;
      &lt;td&gt;$20&lt;/td&gt;
      &lt;td&gt;$6&lt;/td&gt;
      &lt;td&gt;$12&lt;/td&gt;
      &lt;td&gt;$0&lt;/td&gt;
      &lt;td&gt;$38&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;$26&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Totals&lt;/td&gt;
      &lt;td&gt;$100&lt;/td&gt;
      &lt;td&gt;$24&lt;/td&gt;
      &lt;td&gt;$48&lt;/td&gt;
      &lt;td&gt;$48&lt;/td&gt;
      &lt;td&gt;$172&lt;/td&gt;
      &lt;td&gt;$172&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Both columns collect exactly $172. The difference is entirely in where the $48 bottle lands: by headcount Sam pays $12 for wine he did not drink, and by consumption the three drinkers pay $16 each instead.&lt;/p&gt;

&lt;p&gt;Add a 20% tip and the gap widens, because tip rides on the subtotal. Sam’s total goes from $45.60 by headcount to $31.20 by consumption, a $14.40 swing on one bottle he never touched. The drinkers each move $4.80 the other way.&lt;/p&gt;

&lt;p&gt;The harder case is the one people actually argue about: Sam had one glass out of six. Splitting a bottle by pours is arithmetically trivial and socially unworkable, because somebody would have had to count. The rule that survives contact with a real table is binary: you were in on the bottle or you weren’t. If Sam took a glass, he is in for a full share. That imprecision is the price of not auditing a wine bottle, and it is worth paying.&lt;/p&gt;

&lt;p&gt;So the board and the bottle follow different rules, and tables go wrong when they treat them as one. The test is visibility: did anyone watch you opt out? Sam refusing wine happened in front of everyone, so the bottle is not his. Nobody could have seen who took two olives and who took five, so the board goes across the head count.&lt;/p&gt;

&lt;h2 id=&quot;what-do-you-do-with-the-leftover-cent&quot;&gt;What do you do with the leftover cent?&lt;/h2&gt;

&lt;p&gt;A bar tab. Six people, everything genuinely shared, &lt;strong&gt;$101.00&lt;/strong&gt;. Divided six ways that is $16.8333…, and there is no way to pay a third of a cent. Maya put down her card.&lt;/p&gt;

&lt;p&gt;Three rules, all defensible:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Person&lt;/th&gt;
      &lt;th&gt;Exact share&lt;/th&gt;
      &lt;th&gt;A: payer takes the remainder&lt;/th&gt;
      &lt;th&gt;B: rotate the remainder&lt;/th&gt;
      &lt;th&gt;C: everyone rounds up&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Maya (paid)&lt;/td&gt;
      &lt;td&gt;$16.8333&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;$16.85&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;$16.83&lt;/td&gt;
      &lt;td&gt;$16.80 effective&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Ivan&lt;/td&gt;
      &lt;td&gt;$16.8333&lt;/td&gt;
      &lt;td&gt;$16.83&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;$16.85&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;$16.84&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Nora&lt;/td&gt;
      &lt;td&gt;$16.8333&lt;/td&gt;
      &lt;td&gt;$16.83&lt;/td&gt;
      &lt;td&gt;$16.83&lt;/td&gt;
      &lt;td&gt;$16.84&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Priya&lt;/td&gt;
      &lt;td&gt;$16.8333&lt;/td&gt;
      &lt;td&gt;$16.83&lt;/td&gt;
      &lt;td&gt;$16.83&lt;/td&gt;
      &lt;td&gt;$16.84&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Sam&lt;/td&gt;
      &lt;td&gt;$16.8333&lt;/td&gt;
      &lt;td&gt;$16.83&lt;/td&gt;
      &lt;td&gt;$16.83&lt;/td&gt;
      &lt;td&gt;$16.84&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Tomas&lt;/td&gt;
      &lt;td&gt;$16.8333&lt;/td&gt;
      &lt;td&gt;$16.83&lt;/td&gt;
      &lt;td&gt;$16.83&lt;/td&gt;
      &lt;td&gt;$16.84&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Collected&lt;/td&gt;
      &lt;td&gt;$101.00&lt;/td&gt;
      &lt;td&gt;$101.00&lt;/td&gt;
      &lt;td&gt;$101.00&lt;/td&gt;
      &lt;td&gt;$101.00&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;strong&gt;A: the payer takes the remainder.&lt;/strong&gt; Six times $16.83 is $100.98, so two cents are orphaned. Put them on the card-holder’s own line: five people send $16.83, Maya’s share becomes $16.85. It costs the payer two cents, everyone can see it, and it is over in one step. This is the right default for a bill you will never think about again.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;B: rotate it.&lt;/strong&gt; Identical arithmetic with a different name on the odd line. Tonight Ivan takes the two cents, next time someone else does. This only means anything in a group that eats together often enough for “next time” to be real. Otherwise it is ceremony, and it costs a conversation to administer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C: everyone rounds up and the payer keeps the surplus.&lt;/strong&gt; The five others send $16.84 each, Maya collects $84.20, and her own cost lands at $16.80, three cents under her exact share. At the cent level that is invisible. At the dollar level it is not: if everyone sends a flat $17.00, Maya collects $85.00 and pays $16.00, an 83-cent discount for holding the card and then chasing five transfers.&lt;/p&gt;

&lt;p&gt;The one rule to avoid is rounding everyone &lt;em&gt;down&lt;/em&gt;, because the payer absorbs the gap without anybody deciding that they should. Two cents does not matter; the habit does, because it scales with the unit. A $487.35 bill split eleven ways is $44.30 a head, and a table that rounds down to a flat $44 collects $484 and leaves the payer $3.35 short, every time, without anyone noticing.&lt;/p&gt;

&lt;h2 id=&quot;which-splitting-rule-fits-which-table&quot;&gt;Which splitting rule fits which table?&lt;/h2&gt;

&lt;p&gt;The right rule depends on the social situation. This is how I would map them, with the way each one fails:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Situation&lt;/th&gt;
      &lt;th&gt;Rule that works&lt;/th&gt;
      &lt;th&gt;Failure mode&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Colleagues, weekday lunch&lt;/td&gt;
      &lt;td&gt;By item, no rounding games&lt;/td&gt;
      &lt;td&gt;An even split taxes whoever ordered least, and that is very often the most junior person at the table&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Close friends, similar orders&lt;/td&gt;
      &lt;td&gt;Even split, rotate the odd cents&lt;/td&gt;
      &lt;td&gt;Fine until one person’s order is consistently double everyone else’s, at which point it becomes a subscription nobody signed up for&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;A date&lt;/td&gt;
      &lt;td&gt;One person pays, or a flat 50/50&lt;/td&gt;
      &lt;td&gt;Itemising reads as an audit, and there is no arithmetic that stops it reading that way&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Group trip, many days&lt;/td&gt;
      &lt;td&gt;A running ledger, settled once at the end&lt;/td&gt;
      &lt;td&gt;Settling every single meal produces forty micro-transfers and one exhausted treasurer&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Family dinner&lt;/td&gt;
      &lt;td&gt;One payer, rotated across occasions&lt;/td&gt;
      &lt;td&gt;Nobody tracks the rotation, so the same person pays for four years and then mentions it once, badly&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Big table, wildly different orders&lt;/td&gt;
      &lt;td&gt;Itemise, but privately, and present the result&lt;/td&gt;
      &lt;td&gt;Itemising out loud takes ten minutes and somebody will leave before it finishes&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;how-do-you-split-a-bill-in-a-foreign-currency&quot;&gt;How do you split a bill in a foreign currency?&lt;/h2&gt;

&lt;p&gt;Use the rate your card actually charged. The problem is that you cannot know that number at the table, and possibly not for two days. Card networks convert at their own daily rate (Visa publishes an &lt;a href=&quot;https://usa.visa.com/support/consumer/travel-support/exchange-rate-calculator.html&quot;&gt;exchange rate calculator&lt;/a&gt; and Mastercard a &lt;a href=&quot;https://www.mastercard.us/en-us/personal/get-support/convert-currency.html&quot;&gt;currency converter&lt;/a&gt;), applied on the settlement date, not the day you ate, and your issuer may add a foreign-transaction fee on top, commonly in the 0-3% range depending on the card. So the rate printed nowhere on the receipt, the rate in your phone’s currency app, and the rate that eventually lands on your statement are three different numbers.&lt;/p&gt;

&lt;p&gt;So fix one rate for the whole trip, in advance, and tell everyone which one. “We’re using 1.08 for the week” is checkable and applies to everyone equally. A rate that changes per meal is no more accurate, it is harder to audit, and it invites the suspicion that whoever picked it picked favourably. Whoever fronted the card can reconcile against their statement afterwards if the drift turns out to be material, which for a week of dinners it almost never is.&lt;/p&gt;

&lt;h2 id=&quot;why-the-arithmetic-was-never-the-hard-part&quot;&gt;Why the arithmetic was never the hard part&lt;/h2&gt;

&lt;p&gt;Everything above is a solved problem. A calculator handles it, and a spreadsheet handles it better.&lt;/p&gt;

&lt;p&gt;Bills still get split badly because &lt;em&gt;proposing&lt;/em&gt; the fair rule costs something. Saying “let’s split by item” at a table of six means saying out loud that you noticed what other people ordered and priced it. It is arithmetically neutral and socially loaded, and most people will hand over $20 they do not owe rather than be the one who brought a calculator to dinner. I wrote about the same dynamic from the other side in &lt;a href=&quot;/journal/splitting-a-valentines-dinner-without-making-it-weird/&quot;&gt;how to split a Valentine’s dinner without making it weird&lt;/a&gt;: the $20 nobody mentions, compounding across a year of dinners into an unfairness that nobody can point at afterwards.&lt;/p&gt;

&lt;p&gt;The design answer is to move the itemising off the table: do it privately, on one phone, in under a minute, and hand each person a finished number. People do not mind receiving a total. What they mind is watching one get built about them.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/apps/rightsplit/&quot;&gt;RightSplit&lt;/a&gt; is built around that. Scan the receipt with Apple’s on-device &lt;a href=&quot;https://developer.apple.com/documentation/vision&quot;&gt;Vision framework&lt;/a&gt;, tap each line onto whoever ordered it, split the shared plates among the people who shared them, apply a proportional tip, and send everyone their own line over iMessage or WhatsApp. Only the person holding the phone needs it installed. It is iPhone-only. Equal splitting, the tip calculator and your first receipt scan are free; item-level assignment, the subject of this whole post, is Pro+, at $3.99 a year or $7.99 once. The OCR is exactly as good as Apple’s: clean thermal receipts read reliably, faded or badly-creased ones will occasionally mis-read a line, and you fix that by tapping the line and correcting it before you split. Nothing is uploaded, which is the rule every app I ship runs on and which the &lt;a href=&quot;/transparency/&quot;&gt;transparency page&lt;/a&gt; states per app.&lt;/p&gt;

&lt;p&gt;Where it mostly stops is at one table on one night. Pro+ adds Spaces (a trip, a shared flat) that collect receipts and expenses on your phone and produce a who-pays-whom settle-up plan, but there are no accounts and no sync. If what you have is four flatmates, a shared electricity bill, and eight months of who-owes-whom that everyone wants to log and check from their own phone, &lt;a href=&quot;/alternatives/splitwise/&quot;&gt;Splitwise&lt;/a&gt; is the right tool, since a shared running balance is its whole reason for existing. &lt;a href=&quot;/alternatives/tricount/&quot;&gt;Tricount&lt;/a&gt; is that same answer shaped for trips, and &lt;a href=&quot;/alternatives/settle-up/&quot;&gt;Settle Up&lt;/a&gt; for groups who want the ledger without the social layer. &lt;a href=&quot;/alternatives/tab/&quot;&gt;Tab&lt;/a&gt; does item-level splitting for free, which is precisely the feature RightSplit puts behind Pro+. And if you want the split and the payment in one place, &lt;a href=&quot;/alternatives/venmo-split/&quot;&gt;Venmo’s split feature&lt;/a&gt; does that; RightSplit deliberately does not, because producing a number and letting everyone pay however they already pay is a smaller promise that survives people switching payment apps.&lt;/p&gt;

&lt;p&gt;RightSplit splits in the receipt’s currency. With Pro+ it shows each total’s approximate value in your home currency and can settle a mixed-currency Space in one currency, using the European Central Bank’s daily rates; without Pro+, on a trip you are doing the conversion yourself, once, on the totals, which is what the fixed-rate advice above amounts to anyway. If the thing you are actually trying to fix is your own recurring spending rather than a table’s dinner, the &lt;a href=&quot;/guides/bill-tracker-without-bank-connection/&quot;&gt;bill tracker without a bank connection&lt;/a&gt; guide is a closer fit than any of this.&lt;/p&gt;

&lt;h2 id=&quot;tldr&quot;&gt;TL;DR&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Assign items first, then hand out tax and tip in proportion to each person’s subtotal.&lt;/strong&gt; On a $120 subtotal, the $58 ribeye carries $11.60 of a 20% tip and the $14 salad carries $2.80, where an even split would charge each of them $6.00.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;An even split is not neutral.&lt;/strong&gt; At a table of four with a $58 order and a $14 order, it moves $20.62 from the light eater to the heavy one in a single dinner.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Shared plates go to the people who shared them.&lt;/strong&gt; One person abstaining from a $48 bottle is a $14.40 swing once tip is included, and the workable test is whether the table saw them opt out.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The leftover cents need a rule, and three are defensible.&lt;/strong&gt; The payer takes the remainder, rotate it, or everyone rounds up and the payer keeps the surplus. Rounding everyone down is the only version that under-collects silently.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;In a foreign currency, fix one rate for the whole trip and say which one.&lt;/strong&gt; The real rate is set at settlement, plus roughly 0-3% in issuer fees, and you cannot know it at the table.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The math was never the bottleneck.&lt;/strong&gt; Itemising in front of people reads as an audit; do it privately and present a result.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Any of these rules works, as long as the table picks it before the bill arrives.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>PPL, Upper/Lower, 5/3/1: choosing a strength program you will still be running in twelve weeks</title>
    <link href="https://lagerland-apps.github.io/journal/choosing-a-strength-program-you-will-finish/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/choosing-a-strength-program-you-will-finish/</id>
    <published>2026-08-06T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Run two competently written strength programs, same person, same twelve weeks, and the results barely differ. Finishing twelve weeks versus quitting in week five makes an enormous difference. So the useful comparison is which program survives your actual calendar, and that is what this post compares, with the progression rules spelled out.</summary>
    <content type="html">&lt;p&gt;Most program arguments are about the wrong variable.&lt;/p&gt;

&lt;p&gt;Ask whether PPL beats Upper/Lower and you get a hundred confident answers about frequency, volume distribution and recovery. All of it is real, and almost none of it decides anything. Run two competently written programs, same person, same twelve weeks, and you would struggle to see the difference in your own logbook.&lt;/p&gt;

&lt;p&gt;The outcome depends on whether you are still running the thing in week ten: the Tuesday you leave the office at 19:40, the fortnight in March when everyone in the house is ill. So the comparison below is built around days per week, session length, and the specific way each program breaks.&lt;/p&gt;

&lt;h2 id=&quot;which-strength-program-should-you-run&quot;&gt;Which strength program should you run?&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Program&lt;/th&gt;
      &lt;th&gt;Days/week&lt;/th&gt;
      &lt;th&gt;Realistic session&lt;/th&gt;
      &lt;th&gt;Progression model&lt;/th&gt;
      &lt;th&gt;Frequency per muscle&lt;/th&gt;
      &lt;th&gt;Suits&lt;/th&gt;
      &lt;th&gt;Characteristic failure mode&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Full body 3×&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;50 to 70 min&lt;/td&gt;
      &lt;td&gt;Linear, then double progression&lt;/td&gt;
      &lt;td&gt;~3×&lt;/td&gt;
      &lt;td&gt;Beginners, unpredictable weeks, returning lifters&lt;/td&gt;
      &lt;td&gt;Sessions creep longer as the squat gets heavy. Near-maximal squatting three times a week stops being recoverable, and people quit instead of cutting back.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Upper/Lower 4×&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;55 to 75 min&lt;/td&gt;
      &lt;td&gt;Double progression, or percentage blocks&lt;/td&gt;
      &lt;td&gt;2×&lt;/td&gt;
      &lt;td&gt;Intermediates with four genuinely reliable slots&lt;/td&gt;
      &lt;td&gt;The fourth day gets dropped, and without anyone deciding it the split becomes a lopsided three-day plan where legs are trained once.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;PPL 6×&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;6&lt;/td&gt;
      &lt;td&gt;45 to 75 min&lt;/td&gt;
      &lt;td&gt;Double progression, usually per exercise&lt;/td&gt;
      &lt;td&gt;2×&lt;/td&gt;
      &lt;td&gt;People who want six gym days and have a short commute&lt;/td&gt;
      &lt;td&gt;Miss two sessions and a fixed weekly rotation desynchronises. The make-up logic collapses within a fortnight.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Starting Strength / novice LP&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;45 to 75 min, growing&lt;/td&gt;
      &lt;td&gt;Linear: add load every session&lt;/td&gt;
      &lt;td&gt;3×&lt;/td&gt;
      &lt;td&gt;Untrained or detrained lifters, roughly the first 3 to 9 months of barbell work&lt;/td&gt;
      &lt;td&gt;The linear phase ends and nobody notices. Lifters reset the same 10% three or four times when they should change model.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;5/3/1&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;3 to 4&lt;/td&gt;
      &lt;td&gt;40 to 60 min plus assistance&lt;/td&gt;
      &lt;td&gt;Percentage-based off a Training Max, 4-week cycle&lt;/td&gt;
      &lt;td&gt;1× per main lift, ~2× per muscle with assistance&lt;/td&gt;
      &lt;td&gt;Intermediates who want a long plan and few weekly decisions&lt;/td&gt;
      &lt;td&gt;It feels light in month one, so the Training Max gets inflated. The AMRAP set becomes a grinder and stops adding reps.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;strong&gt;Weekly frequency per muscle doesn’t separate these programs much.&lt;/strong&gt; Full body and PPL sit at three and two, and once weekly volume is held equal, the frequency research shows nothing dramatic in either direction. Greg Nuckols’ &lt;a href=&quot;https://www.strongerbyscience.com/training-frequency/&quot;&gt;review of the frequency literature at Stronger By Science&lt;/a&gt; is the most careful public summary I know of. Twice per muscle per week is a fine default and nothing more binding than that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The failure modes are specific.&lt;/strong&gt; PPL fails because six fixed slots give a week six places to break; the volume is fine. Novice linear progression fails because it is designed to end, and almost nobody has a plan for what comes after.&lt;/p&gt;

&lt;h2 id=&quot;what-does-each-progression-model-actually-tell-you-to-do&quot;&gt;What does each progression model actually tell you to do?&lt;/h2&gt;

&lt;p&gt;The split is the easy half. The progression model decides what you do on a Tuesday when the bar feels heavy, and it is where most self-written programs go vague.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Model&lt;/th&gt;
      &lt;th&gt;What you add&lt;/th&gt;
      &lt;th&gt;When you add it&lt;/th&gt;
      &lt;th&gt;On a failed session&lt;/th&gt;
      &lt;th&gt;Deload rule&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Linear&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Load&lt;/td&gt;
      &lt;td&gt;Every session: typically 2.5 kg / 5 lb upper body, 5 kg / 10 lb lower body early on&lt;/td&gt;
      &lt;td&gt;Repeat the same weight next session. After two or three consecutive failures, reset ~10% and build back&lt;/td&gt;
      &lt;td&gt;The reset &lt;em&gt;is&lt;/em&gt; the deload. The classic novice template has no scheduled deload weeks&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Double progression&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Reps first, then load&lt;/td&gt;
      &lt;td&gt;Add load only when every set hits the top of the bracket. In 3 × 8 to 12: stay at the weight until all three sets reach 12, then add the smallest increment and drop back to 8&lt;/td&gt;
      &lt;td&gt;Nothing special. Repeat the load and try for one more rep. A failed increase is a normal week&lt;/td&gt;
      &lt;td&gt;Cut load ~10% or drop a set for a week when two or three lifts stall at the same time&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Percentage / Training Max (5/3/1)&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;A fixed increment to the &lt;em&gt;Training Max&lt;/em&gt; (your 1RM is left alone)&lt;/td&gt;
      &lt;td&gt;Once per completed cycle: +2.5 kg / 5 lb upper, +5 kg / 10 lb lower&lt;/td&gt;
      &lt;td&gt;If the AMRAP set falls below the prescribed minimum reps, hold the Training Max or cut it ~10% next cycle&lt;/td&gt;
      &lt;td&gt;Built in. Week four is the deload at 40/50/60% of the Training Max&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Autoregulated / RPE&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Load, chosen to hit a target RPE or reps-in-reserve&lt;/td&gt;
      &lt;td&gt;Every set. A top set at RPE 8, back-offs a set percentage below it&lt;/td&gt;
      &lt;td&gt;No session counts as failed, only lighter. The load that hits RPE 8 today is the prescription&lt;/td&gt;
      &lt;td&gt;Deload when the load at a given RPE drops for two or more sessions, or on a fixed 4 to 6 week cadence&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Here is a worked example, because double progression is the one people describe correctly and then run incorrectly. Dumbbell rows, 3 sets of 8 to 12, at 30 kg. Session one: 12, 10, 9. No increase, because two sets missed the top. Session two: 12, 12, 10. Still no. Session three: 12, 12, 12. Now you take the smallest increment your gym has, go to 32 kg, and expect roughly 9, 8, 8. You haven’t gone backwards; the bracket resets and you climb it again, which may take five weeks. The other versions of the add-weight rule, and the plate arithmetic for lifts where 2.5 kg is too big a jump, are in &lt;a href=&quot;/journal/double-progression-explained/&quot;&gt;double progression explained&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;what-is-531-exactly&quot;&gt;What is 5/3/1, exactly?&lt;/h2&gt;

&lt;p&gt;5/3/1 comes from &lt;a href=&quot;https://www.jimwendler.com/blogs/jimwendler-com/101065094-5-3-1-for-a-beginner&quot;&gt;Jim Wendler&lt;/a&gt;. Its central idea is the Training Max: you programme off 85-90% of your tested one-rep max (the original template uses 90%) so the percentages stay honest on a bad week. Every percentage below is of the Training Max, not your actual max.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Week&lt;/th&gt;
      &lt;th&gt;Set 1&lt;/th&gt;
      &lt;th&gt;Set 2&lt;/th&gt;
      &lt;th&gt;Top set&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;65% × 5&lt;/td&gt;
      &lt;td&gt;75% × 5&lt;/td&gt;
      &lt;td&gt;85% × 5+&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2&lt;/td&gt;
      &lt;td&gt;70% × 3&lt;/td&gt;
      &lt;td&gt;80% × 3&lt;/td&gt;
      &lt;td&gt;90% × 3+&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;75% × 5&lt;/td&gt;
      &lt;td&gt;85% × 3&lt;/td&gt;
      &lt;td&gt;95% × 1+&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;4 (deload)&lt;/td&gt;
      &lt;td&gt;40% × 5&lt;/td&gt;
      &lt;td&gt;50% × 5&lt;/td&gt;
      &lt;td&gt;60% × 5&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The “+” is where the progress shows. You take that last set for as many quality reps as you have, and its rep count is your progress signal, while the fixed sets stay at the same percentages forever. Finish the cycle, add 2.5 kg to the upper-body Training Maxes and 5 kg to the lower-body ones, and run it again. That is roughly a year of programming decided in one sitting, which is the appeal.&lt;/p&gt;

&lt;p&gt;The failure mode is self-inflicted. Month one feels easy, so people set the Training Max at their real max, or add 5 kg a cycle to everything. Six cycles later the top set is one grinding rep. Wendler’s own advice is worth taking: start lighter than you think.&lt;/p&gt;

&lt;h2 id=&quot;how-many-days-a-week-should-you-lift&quot;&gt;How many days a week should you lift?&lt;/h2&gt;

&lt;p&gt;The floor is well established. The US &lt;a href=&quot;https://odphp.health.gov/our-work/nutrition-physical-activity/physical-activity-guidelines&quot;&gt;Physical Activity Guidelines for Americans&lt;/a&gt; recommend muscle-strengthening activity on two or more days a week for adults, covering all major muscle groups. That is a health floor, and building strength usually takes more.&lt;/p&gt;

&lt;p&gt;For building strength, most sustainable programs sit at three to five days. Work out your number from the past, though. Open whatever record you have of the last eight weeks and count the sessions. If it is 19, you train two and a bit days a week, and a six-day PPL is a wish. Add a day only after the existing days have been boring and reliable for a month.&lt;/p&gt;

&lt;p&gt;The most common mistake I see is people picking a program for the version of themselves that exists in January.&lt;/p&gt;

&lt;h2 id=&quot;when-does-a-novice-linear-progression-end&quot;&gt;When does a novice linear progression end?&lt;/h2&gt;

&lt;p&gt;Novice linear progression (&lt;a href=&quot;https://startingstrength.com/&quot;&gt;Mark Rippetoe’s Starting Strength&lt;/a&gt; is the best-known version) works because an untrained lifter recovers between sessions in a couple of days and adapts fast enough to add load every session. That window is real, and it closes, usually somewhere between three and nine months of consistent barbell work depending on age, food and sleep.&lt;/p&gt;

&lt;p&gt;The published stall rule is to repeat the weight, then after two or three consecutive failed sessions reset roughly 10% and build back. The rule doesn’t tell you how many times to do that.&lt;/p&gt;

&lt;p&gt;The heuristic I use: &lt;strong&gt;two resets on the same lift with no new personal record between them means the linear phase is over for that lift.&lt;/strong&gt; That applies to the lift, not to you or your other lifts. The press stalls long before the deadlift, so the press moves to double progression while the squat keeps running linear. A lifter can be a novice on one bar and an intermediate on another for months. Treating “am I a beginner?” as one global fact is what keeps people resetting the same 10% four times.&lt;/p&gt;

&lt;h2 id=&quot;how-to-choose-in-four-questions&quot;&gt;How to choose, in four questions&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;How many days did you actually train in the last eight weeks?&lt;/strong&gt; Count them and divide by eight. That is your days per week, whatever you intended and whatever your best month looked like. Three means full body. Four means Upper/Lower. Six means PPL, if and only if six is a number you have hit before.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;How long is a session on your worst weekday?&lt;/strong&gt; Under 50 minutes, two things fit: full body three times a week, or 5/3/1 with trimmed assistance. A 75-minute PPL leg day does not shrink to 45 minutes; it gets skipped. Most of any session is rest, and &lt;a href=&quot;/journal/how-long-to-rest-between-sets/&quot;&gt;how long you rest between sets&lt;/a&gt; is the first thing to trim, starting with the isolation work and leaving the heavy lifts alone.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;What is your training age in this specific lift?&lt;/strong&gt; Under six months of consistent barbell work: linear. Six months to two years: double progression. Beyond that: percentage cycles or autoregulation, and expect to measure progress per quarter.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;What has hurt, and what made it hurt?&lt;/strong&gt; If flat barbell benching aggravates a shoulder, no split solves that. Pick a structure organised by movement pattern, so you can swap the movement without deleting a day. A fixed list of named exercises makes that harder.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is training information, not medical advice. If you are working around an injury or a condition that affects loading, have a clinician or a coach watch you lift.&lt;/p&gt;

&lt;h2 id=&quot;why-the-log-is-the-part-that-decides-it&quot;&gt;Why the log is the part that decides it&lt;/h2&gt;

&lt;p&gt;Everything above assumes you know what you did last time, and that assumption carries more weight than any of the programming.&lt;/p&gt;

&lt;p&gt;Linear progression is the only model in that second table you can run from memory, because the rule is &lt;em&gt;last time plus 2.5 kg&lt;/em&gt;. Every other one is a rule applied to a record. Double progression needs three set counts from last session. A 5/3/1 cycle needs a Training Max and every AMRAP rep count going back months. Autoregulation needs a history of what a given RPE cost you in kilos, or the number is a feeling with a decimal point attached. That is the unglamorous reason logging apps exist, and the two I build take different sides of it.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/apps/liftlog/&quot;&gt;LiftLog&lt;/a&gt; is the iPhone one. It ships 40 programs, among them StrongLifts 5×5, Starting Strength, PPL, Upper/Lower, full-body splits, and 5/3/1, and each exercise carries one of the progression models above: linear, double progression, percent of a Training Max, or RPE. In the 5/3/1 programs the main lifts run the four-week wave from a separate Training Max field, and beating the prescribed reps on the AMRAP top set raises the Training Max. The deload is per lift: three missed sessions in a row and that exercise’s weight drops to 90%, both numbers editable. It does not plan undulating or block periodization for you. RPE is optional; you can add it to any logged set, and no set requires it. The constraints: iPhone only, no Apple Watch app, and pricing is a seven-day trial with no card followed by a one-time pay-what-you-can purchase between $9.99 and $39.99. The &lt;a href=&quot;/journal/liftlog-pay-what-you-can/&quot;&gt;reasoning behind that model&lt;/a&gt; has its own post.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/apps/gymlogger-x/&quot;&gt;GymLogger X&lt;/a&gt; is the sibling with an Apple Watch app. Core logging is free, and Pro is $1.99/month, $17.99/year, or $39.99 lifetime. It exists because I wanted to log a set from the wrist without carrying a phone to the rack, which is &lt;a href=&quot;/journal/the-strength-logger-no-one-asked-for/&quot;&gt;the entire argument for it&lt;/a&gt;. Its plateau rule, a Pro feature, is published in plain English: an exercise is flagged when its estimated 1RM stops clearing a threshold set by your own 90-day rate of gain on that lift, across four sessions in which your volume held steady (fell by no more than 3%).&lt;/p&gt;

&lt;p&gt;Neither is right for everyone, and several competitors solve problems mine do not.&lt;/p&gt;

&lt;p&gt;If your programs die because &lt;em&gt;choosing&lt;/em&gt; one is the friction, &lt;a href=&quot;/alternatives/fitbod/&quot;&gt;Fitbod&lt;/a&gt; is the better tool. It generates each session for you: you open it and it tells you what to do today, adjusted for yesterday. A manual logger can’t replace that with better templates. The trade-off is subscription-only pricing and reasoning you can’t inspect.&lt;/p&gt;

&lt;p&gt;If accountability is what breaks, &lt;a href=&quot;/alternatives/hevy/&quot;&gt;Hevy&lt;/a&gt; has the most generous free tier in the category and a social feed that, for some people, is what gets them to the gym on a Thursday. I do not build social features and never will, so for those people I am the wrong studio. &lt;a href=&quot;/alternatives/strong-workout-app/&quot;&gt;Strong&lt;/a&gt; is the best-established logger here, with full standalone Apple Watch support, and &lt;a href=&quot;/alternatives/caliber/&quot;&gt;Caliber&lt;/a&gt; pairs you with a human coach, the only option listed that can change your program when your week changes.&lt;/p&gt;

&lt;p&gt;For the category sorted by pricing model, see the &lt;a href=&quot;/guides/workout-app-without-subscription/&quot;&gt;guide to workout apps without a subscription&lt;/a&gt;; what my apps collect is on the &lt;a href=&quot;/transparency/&quot;&gt;transparency page&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;tldr&quot;&gt;TL;DR&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Adherence beats programming.&lt;/strong&gt; Between two competent programs run for twelve weeks the difference is small; between finishing and quitting in week five it is enormous.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Count your days per week; don’t choose them.&lt;/strong&gt; Count the sessions you did over the last eight weeks and divide by eight. Three: full body. Four: Upper/Lower. Six: PPL, only if you have hit six before.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Each split has one characteristic failure.&lt;/strong&gt; PPL desynchronises after two missed sessions. Upper/Lower loses its fourth day. Full body’s sessions grow until heavy squatting three times a week stops being recoverable. Novice linear progression ends and nobody notices.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Match the progression model to training age, per lift.&lt;/strong&gt; Linear under six months, double progression to roughly two years, then 5/3/1-style percentage cycles or RPE autoregulation.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Double progression in one line:&lt;/strong&gt; stay at the weight until every set hits the top of the bracket, then add the smallest increment and drop back to the bottom.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Only linear progression runs from memory.&lt;/strong&gt; Every other model is a rule applied to a written record, so the log decides whether you finish the twelve weeks more than the template does.&lt;/li&gt;
&lt;/ul&gt;
</content>
  </entry>

  <entry>
    <title>How to create an App Store Connect API key: team or individual, the right role, and a .p8 you only get once</title>
    <link href="https://lagerland-apps.github.io/journal/app-store-connect-api-key-setup/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/app-store-connect-api-key-setup/</id>
    <published>2026-08-01T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Every tool that talks to App Store Connect on your behalf, from fastlane to a Mac client like mine, starts with the same three things: an Issuer ID, a Key ID and a .p8 file. Creating them takes two minutes. Choosing the right kind of key and the right role is where people go wrong, and the .p8 download gives you exactly one chance.</summary>
    <content type="html">&lt;p&gt;An App Store Connect API key is a key pair. Apple keeps the public half; you download the private half as a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.p8&lt;/code&gt; file and use it to sign the short-lived tokens that every API request carries. A tool will ask you for four things, listed below with where each one lives.&lt;/p&gt;

&lt;h2 id=&quot;what-does-a-tool-need-from-you&quot;&gt;What does a tool need from you?&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Item&lt;/th&gt;
      &lt;th&gt;What it is&lt;/th&gt;
      &lt;th&gt;Where to find it&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Issuer ID&lt;/td&gt;
      &lt;td&gt;A UUID that identifies your team, the same for every team key&lt;/td&gt;
      &lt;td&gt;Top of Users and Access &amp;gt; Integrations &amp;gt; App Store Connect API, with a Copy button&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Key ID&lt;/td&gt;
      &lt;td&gt;A short ID for one key, such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2X9R4HXF34&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Next to each key in the Active list; hover to Copy Key ID&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Private key (.p8)&lt;/td&gt;
      &lt;td&gt;The private half of the key pair, a small text file&lt;/td&gt;
      &lt;td&gt;Download API Key link, available a single time&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Role&lt;/td&gt;
      &lt;td&gt;What the key is allowed to do&lt;/td&gt;
      &lt;td&gt;Chosen under Access when you generate the key, fixed after that&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.p8&lt;/code&gt; file is a PEM text file that begins with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-----BEGIN PRIVATE KEY-----&lt;/code&gt;. If a tool complains that your key is the wrong format and the file says &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BEGIN EC PRIVATE KEY&lt;/code&gt;, you probably have a key made with OpenSSL, not one downloaded from App Store Connect.&lt;/p&gt;

&lt;h2 id=&quot;team-key-or-individual-key&quot;&gt;Team key or individual key?&lt;/h2&gt;

&lt;p&gt;Apple offers two kinds, and picking the wrong one causes more trouble than any of the setup steps.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; &lt;/th&gt;
      &lt;th&gt;Team key&lt;/th&gt;
      &lt;th&gt;Individual key&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Who can create it&lt;/td&gt;
      &lt;td&gt;Account Holder or Admin&lt;/td&gt;
      &lt;td&gt;Most users, from their own profile (Account Holder, Admin, App Manager, Customer Support, Developer or Marketing), unless an Admin removed that permission&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Access&lt;/td&gt;
      &lt;td&gt;All apps in the account, with the role you pick; app access can’t be limited&lt;/td&gt;
      &lt;td&gt;The apps and roles of the user who made it&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Can’t use&lt;/td&gt;
      &lt;td&gt;Only what its role rules out&lt;/td&gt;
      &lt;td&gt;Provisioning endpoints, Sales and Finance, notaryTool&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;How many&lt;/td&gt;
      &lt;td&gt;Several; Apple lets you generate multiple&lt;/td&gt;
      &lt;td&gt;One active key per user&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;In the token&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;iss&lt;/code&gt; set to the Issuer ID&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sub&lt;/code&gt; set to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;user&lt;/code&gt;, no &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;iss&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Sources: Apple’s &lt;a href=&quot;https://developer.apple.com/documentation/appstoreconnectapi/creating-api-keys-for-app-store-connect-api&quot;&gt;Creating API Keys for App Store Connect API&lt;/a&gt; and the &lt;a href=&quot;https://developer.apple.com/help/app-store-connect/get-started/app-store-connect-api&quot;&gt;App Store Connect API help page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Use a team key for anything that works for the whole account: CI, a metadata tool, a sales dashboard. Use an individual key when a script should only ever see what one person sees. Since individual keys can’t read Sales and Finance, they’re no use for revenue tools at all.&lt;/p&gt;

&lt;h2 id=&quot;how-do-you-create-a-team-key-step-by-step&quot;&gt;How do you create a team key, step by step?&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Request access, once.&lt;/strong&gt; The Account Holder goes to Users and Access &amp;gt; Integrations, clicks Request Access, agrees to the terms and submits. Apple says requests are reviewed case by case.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Open Team Keys.&lt;/strong&gt; In Users and Access &amp;gt; Integrations, with App Store Connect API selected in the left column, choose the Team Keys tab.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Generate.&lt;/strong&gt; Click Generate API Key, or the + button if you already have an active key.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Name it.&lt;/strong&gt; The name is only for you. Name it after the tool or the machine that will use it, so you know what breaks when you revoke it later.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Pick the role.&lt;/strong&gt; Under Access, choose the role. Apple says you can’t edit a key’s name or access level afterwards; to change either, you revoke the key and make a new one.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Click Generate&lt;/strong&gt;, then &lt;strong&gt;Download API Key&lt;/strong&gt; next to the new key. Save the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.p8&lt;/code&gt; before you leave the page.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Copy the Issuer ID and Key ID&lt;/strong&gt; into the tool, along with the file.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;An individual key is shorter: click your name at the top right, Edit Profile, then Generate Key under Individual API Key, and Download.&lt;/p&gt;

&lt;h2 id=&quot;which-role-should-the-key-have&quot;&gt;Which role should the key have?&lt;/h2&gt;

&lt;p&gt;The roles for keys are the same ones you give people on your team. The rows below are from Apple’s &lt;a href=&quot;https://developer.apple.com/help/account/access/roles&quot;&gt;role permissions table&lt;/a&gt;, narrowed to what API tools usually do:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Role&lt;/th&gt;
      &lt;th&gt;Edit App Store details&lt;/th&gt;
      &lt;th&gt;Create versions, submit apps&lt;/th&gt;
      &lt;th&gt;Reply to reviews&lt;/th&gt;
      &lt;th&gt;Sales and Trends reports&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Admin&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;App Manager&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Marketing&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;Create versions only&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Customer Support&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Developer&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Sales&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Finance&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Pick the smallest role that covers the job. A screenshot or metadata tool fits App Manager. A revenue dashboard fits Sales or Finance. A tool that edits metadata, replies to reviews and reads sales needs Admin, and Apple’s docs single that role out: an Admin key can create and delete users. Keep that file somewhere better than your Downloads folder.&lt;/p&gt;

&lt;h2 id=&quot;where-should-the-p8-file-live&quot;&gt;Where should the .p8 file live?&lt;/h2&gt;

&lt;p&gt;Apple’s guidance is short. Treat the private key like a password; don’t share it, store it in a code repository or ship it in client-side code; and revoke it at once if it’s lost or exposed. Apple keeps no copy, so the file you downloaded is the only one.&lt;/p&gt;

&lt;p&gt;In practice that means a password manager, the macOS Keychain, or your CI provider’s secret store, and then deleting the stray copy in Downloads. One key per tool helps too. Apple lets you generate multiple team keys, and if each tool has its own, revoking one doesn’t take the others down with it.&lt;/p&gt;

&lt;h2 id=&quot;how-do-you-revoke-a-key&quot;&gt;How do you revoke a key?&lt;/h2&gt;

&lt;p&gt;Revoking is immediate and permanent. Apple’s &lt;a href=&quot;https://developer.apple.com/documentation/appstoreconnectapi/revoking-api-keys&quot;&gt;Revoking API Keys&lt;/a&gt; page says a revoked key can’t be reinstated; revoked keys stay listed for 30 days under Revoked.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;For a team key, an Account Holder or Admin opens Users and Access &amp;gt; Integrations &amp;gt; App Store Connect API, chooses Team Keys, clicks Edit, selects the key, clicks Revoke Key and confirms.&lt;/li&gt;
  &lt;li&gt;For someone else’s individual key, it’s the same place under the Individual Keys tab, again as an Account Holder or Admin.&lt;/li&gt;
  &lt;li&gt;For your own individual key, open Edit Profile, find Individual API Key and click Revoke.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Revoke a key when a laptop holding the file is lost, when someone who had a copy leaves, and when you retire the tool that used it.&lt;/p&gt;

&lt;h2 id=&quot;what-is-a-jwt-in-one-paragraph&quot;&gt;What is a JWT, in one paragraph?&lt;/h2&gt;

&lt;p&gt;The API never sees your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.p8&lt;/code&gt; file. Each request carries a JSON Web Token (&lt;a href=&quot;https://tools.ietf.org/html/rfc7519&quot;&gt;RFC 7519&lt;/a&gt;) that the tool builds and signs on your machine: a header saying it’s signed with ES256 and naming your Key ID (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kid&lt;/code&gt;), and a payload with your Issuer ID (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;iss&lt;/code&gt;), the time it was issued (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;iat&lt;/code&gt;), its expiry (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exp&lt;/code&gt;) and the audience &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;appstoreconnect-v1&lt;/code&gt;, optionally narrowed with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scope&lt;/code&gt; list of allowed requests. Apple checks the signature against the public half it kept, so a valid signature proves the request came from whoever holds the private key. Tokens with a lifetime over 20 minutes are rejected for most requests, and Apple suggests reusing one token across requests until it expires (&lt;a href=&quot;https://developer.apple.com/documentation/appstoreconnectapi/generating-tokens-for-api-requests&quot;&gt;Generating Tokens for API Requests&lt;/a&gt;).&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Header:  { &quot;alg&quot;: &quot;ES256&quot;, &quot;kid&quot;: &quot;2X9R4HXF34&quot;, &quot;typ&quot;: &quot;JWT&quot; }
Payload: { &quot;iss&quot;: &quot;57246542-96fe-1a63-e053-0824d011072a&quot;,
           &quot;iat&quot;: 1528407600, &quot;exp&quot;: 1528408800,
           &quot;aud&quot;: &quot;appstoreconnect-v1&quot; }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Those are Apple’s own example values: an exp 1,200 seconds after iat is exactly the 20-minute ceiling.&lt;/p&gt;

&lt;h2 id=&quot;what-do-the-common-errors-mean&quot;&gt;What do the common errors mean?&lt;/h2&gt;

&lt;p&gt;A token App Store Connect won’t accept usually comes back as 401 with the code &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NOT_AUTHORIZED&lt;/code&gt;. The usual causes are an Issuer ID and Key ID that don’t belong together, a token signed with a different key than the one its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kid&lt;/code&gt; names, a lifetime over 20 minutes, or a computer clock that’s off. Apple’s &lt;a href=&quot;https://developer.apple.com/documentation/appstoreconnectapi/about-the-http-status-code&quot;&gt;status code table&lt;/a&gt; lists 403 Forbidden for a revoked key, a badly formatted token, or an operation the key isn’t allowed to do. If the token works for some requests and not others, it’s the role. 429 means you’ve hit the rate limit for that key.&lt;/p&gt;

&lt;h2 id=&quot;how-appmeta-uses-your-key&quot;&gt;How AppMeta uses your key&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/apps/appmeta/&quot;&gt;AppMeta&lt;/a&gt;, the Mac client for App Store Connect I &lt;a href=&quot;/journal/native-mac-client-for-app-store-connect/&quot;&gt;wrote about in February&lt;/a&gt;, takes a team key: it asks for the Issuer ID, the Key ID and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.p8&lt;/code&gt; file, so individual keys, which have no Issuer ID, don’t fit it. Before it saves anything it signs a token and asks App Store Connect for your app list, so a mismatched ID or a revoked key shows up as an error on the setup screen, before you’ve saved anything.&lt;/p&gt;

&lt;p&gt;The three values go into the macOS Keychain as items that stay on that Mac and don’t sync through iCloud. AppMeta signs 20-minute ES256 tokens locally and reuses each one until it’s about two minutes from expiring, and the only server it sends them to is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;api.appstoreconnect.apple.com&lt;/code&gt;. Removing the account in AppMeta deletes the Keychain items.&lt;/p&gt;

&lt;p&gt;For the role: App Manager covers editing metadata in every localization, the &lt;a href=&quot;/journal/app-store-keyword-field-100-characters/&quot;&gt;keyword field&lt;/a&gt; included, plus creating and submitting versions. Replying to reviews and the sales views need a role that allows them, and for a single key that means Admin. If you’d rather keep revenue on a separate key, the &lt;a href=&quot;/apps/appmeta-pulse/api-access/&quot;&gt;AppMeta Pulse API access page&lt;/a&gt; lists the endpoints Pulse calls and the role it asks for.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>What an iPhone app can actually block, and what it structurally cannot</title>
    <link href="https://lagerland-apps.github.io/journal/what-an-iphone-app-can-actually-block/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/what-an-iphone-app-can-actually-block/</id>
    <published>2026-07-29T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">No third-party iPhone app blocks anything by itself. It asks iOS to do the blocking, through three Apple frameworks with sharp, published limits. Those limits are why your blocker cannot name the apps you blocked, why notifications still arrive, and why the honest answer to &apos;can this be bypassed&apos; is always yes.</summary>
    <content type="html">&lt;p&gt;Ask most people how an app blocker works on iPhone and you get some version of this: the blocker sits in the background, watches what you open, and slams a door when it spots Instagram.&lt;/p&gt;

&lt;p&gt;None of that is possible. A third-party iOS app cannot see which apps you launch, cannot run continuously in the background to watch for one, and cannot draw a single pixel over another app. Every blocker on the App Store asks iOS to do the blocking on its behalf, through three frameworks Apple shipped in 2021 and has extended in small steps since.&lt;/p&gt;

&lt;p&gt;That detail decides what your blocker can do, what it will never do however much you pay, and exactly how you get out, which is the part nobody puts in the App Store screenshots.&lt;/p&gt;

&lt;h2 id=&quot;what-actually-blocks-an-app-on-an-iphone&quot;&gt;What actually blocks an app on an iPhone?&lt;/h2&gt;

&lt;p&gt;Three frameworks, together called the Screen Time API, introduced in the WWDC21 session &lt;a href=&quot;https://developer.apple.com/videos/play/wwdc2021/10123/&quot;&gt;Meet the Screen Time API&lt;/a&gt;. A fourth, ManagedSettingsUI, only controls how the blocking screen looks.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Framework&lt;/th&gt;
      &lt;th&gt;Its one job&lt;/th&gt;
      &lt;th&gt;The types you actually touch&lt;/th&gt;
      &lt;th&gt;What it cannot do&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://developer.apple.com/documentation/familycontrols&quot;&gt;FamilyControls&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;Get permission, and let the user choose apps&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AuthorizationCenter&lt;/code&gt;, &lt;a href=&quot;https://developer.apple.com/documentation/familycontrols/familyactivitypicker&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FamilyActivityPicker&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;https://developer.apple.com/documentation/familycontrols/familyactivityselection&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FamilyActivitySelection&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;Tell your code which apps were chosen&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://developer.apple.com/documentation/managedsettings&quot;&gt;ManagedSettings&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;Apply the restriction&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ManagedSettingsStore&lt;/code&gt;, &lt;a href=&quot;https://developer.apple.com/documentation/managedsettings/shieldsettings&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ShieldSettings&lt;/code&gt;&lt;/a&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.applications&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.applicationCategories&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.webDomains&lt;/code&gt;), &lt;a href=&quot;https://developer.apple.com/documentation/managedsettings/applicationsettings&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ApplicationSettings&lt;/code&gt;&lt;/a&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;denyAppRemoval&lt;/code&gt;)&lt;/td&gt;
      &lt;td&gt;Outlive the authorisation that created it&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://developer.apple.com/documentation/deviceactivity&quot;&gt;DeviceActivity&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;Anything to do with time&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DeviceActivityCenter&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DeviceActivitySchedule&lt;/code&gt;, &lt;a href=&quot;https://developer.apple.com/documentation/deviceactivity/deviceactivityevent&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DeviceActivityEvent&lt;/code&gt;&lt;/a&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DeviceActivityMonitor&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Run your code continuously; the extension wakes on events only&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://developer.apple.com/documentation/managedsettingsui/shieldconfiguration&quot;&gt;ManagedSettingsUI&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;Style the shield&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ShieldConfigurationDataSource&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ShieldActionDelegate&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Anything except draw a title, subtitle, icon and up to two buttons&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;In a real app the sequence is short. Ask for authorisation through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AuthorizationCenter.shared&lt;/code&gt;, in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.individual&lt;/code&gt; mode for self-restriction or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.child&lt;/code&gt; mode for a Family Sharing parent. Present the picker. Put whatever came back into a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ManagedSettingsStore&lt;/code&gt; as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;store.shield.applications&lt;/code&gt;. Register a schedule with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DeviceActivityCenter&lt;/code&gt;, and let iOS wake your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DeviceActivityMonitor&lt;/code&gt; extension at interval boundaries and usage thresholds so it can change the store.&lt;/p&gt;

&lt;p&gt;Two practical limits keep the category smaller than it looks. The Family Controls capability adds the &lt;a href=&quot;https://developer.apple.com/documentation/bundleresources/entitlements/com.apple.developer.family-controls&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;com.apple.developer.family-controls&lt;/code&gt;&lt;/a&gt; entitlement, and distributing it on the App Store requires asking Apple for it. And the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DeviceActivityMonitor&lt;/code&gt; extension is not a daemon: iOS wakes it, gives it a short slice of time, and suspends it. Anything a blocker claims to do “continuously” happens at moments Apple chooses.&lt;/p&gt;

&lt;h2 id=&quot;why-the-blocker-never-learns-which-apps-you-picked&quot;&gt;Why the blocker never learns which apps you picked&lt;/h2&gt;

&lt;p&gt;Of all the design decisions in the API, this one has the biggest consequences.&lt;/p&gt;

&lt;p&gt;The app-selection UI is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FamilyActivityPicker&lt;/code&gt;, and it belongs to Apple, not the developer. It renders out of process, it lists your installed apps, and it returns a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FamilyActivitySelection&lt;/code&gt; containing sets of tokens: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ApplicationToken&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ActivityCategoryToken&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WebDomainToken&lt;/code&gt;. Apple’s documentation for &lt;a href=&quot;https://developer.apple.com/documentation/managedsettings/token&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Token&lt;/code&gt;&lt;/a&gt; describes it as a representation of an app or website “that doesn’t reveal its identity,” and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ApplicationToken&lt;/code&gt; page says the point is to restrict and filter apps without access to personal user data.&lt;/p&gt;

&lt;p&gt;So a blocker holds an opaque blob, which it hands back to ManagedSettings to raise a shield. It never receives a bundle identifier or a display name, and there is no way to reverse the token. A token also means something only to the app that received it, and it stops working the moment you revoke authorisation in Settings, because revocation invalidates the app’s tokens along with its permission.&lt;/p&gt;

&lt;p&gt;For privacy this means a screen-time app physically cannot log that you blocked Grindr, or Robinhood, or your ex’s favourite app. It hasn’t promised not to; it is unable to. That is privacy by construction, and the strongest such guarantee in any category I have shipped into.&lt;/p&gt;

&lt;p&gt;For the product it is a real tax, and every developer in this category pays it:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;You cannot offer a one-tap “block the usual suspects” onboarding, because you cannot name the suspects.&lt;/li&gt;
  &lt;li&gt;You cannot tell the user, in your own copy, which apps are currently shielded.&lt;/li&gt;
  &lt;li&gt;You cannot verify from your own data that a user selected anything at all, so support requests (“it isn’t blocking anything”) turn into guided screenshot sessions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Apple made that trade, not the developer, and I think it made the right one.&lt;/p&gt;

&lt;h2 id=&quot;which-approach-blocks-what&quot;&gt;Which approach blocks what?&lt;/h2&gt;

&lt;p&gt;Five approaches get sold as “app blocking”, and they intercept at completely different layers. Price matters less here than where each one sits in the stack.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Approach&lt;/th&gt;
      &lt;th&gt;What it blocks&lt;/th&gt;
      &lt;th&gt;What it cannot block&lt;/th&gt;
      &lt;th&gt;How it is bypassed&lt;/th&gt;
      &lt;th&gt;Works offline&lt;/th&gt;
      &lt;th&gt;Who it actually suits&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Built-in Screen Time&lt;/strong&gt; (&lt;a href=&quot;https://support.apple.com/guide/iphone/set-up-screen-time-iphbdf9d5495/ios&quot;&gt;Apple’s setup guide&lt;/a&gt;)&lt;/td&gt;
      &lt;td&gt;App and category time limits, Downtime, content ratings, web content; syncs across your devices with Share Across Devices&lt;/td&gt;
      &lt;td&gt;Nothing beyond Apple’s own categories; no custom unlock condition&lt;/td&gt;
      &lt;td&gt;Your own passcode, or the Ignore Limit button&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;Anyone who has not tried it: it is free, and it covers the Mac and iPad too&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Family Controls shield app&lt;/strong&gt; (Opal, one sec, ScreenZen, Jomo, EarnLock)&lt;/td&gt;
      &lt;td&gt;Any app or Apple category you select, plus Safari web domains, on this iPhone&lt;/td&gt;
      &lt;td&gt;Notifications, other devices, and anything after you revoke authorisation&lt;/td&gt;
      &lt;td&gt;Whatever escape hatch the app ships, then revoking authorisation in Settings&lt;/td&gt;
      &lt;td&gt;Yes, because state is local and enforced by iOS&lt;/td&gt;
      &lt;td&gt;People who want an unlock condition other than “wait” or “type your passcode”&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;DNS or VPN content filter&lt;/strong&gt; (&lt;a href=&quot;https://developer.apple.com/documentation/networkextension&quot;&gt;NetworkExtension&lt;/a&gt;)&lt;/td&gt;
      &lt;td&gt;Domains and traffic patterns, system-wide, including apps you did not select&lt;/td&gt;
      &lt;td&gt;Anything on cellular when the profile is off, encrypted DNS inside an app, or a service sharing a CDN with something you need&lt;/td&gt;
      &lt;td&gt;Toggle the VPN off in Settings, roughly three taps&lt;/td&gt;
      &lt;td&gt;No, it is a network mechanism by definition&lt;/td&gt;
      &lt;td&gt;Blocking whole classes of content (ads, adult sites), not a named app&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Separate device or lockbox&lt;/strong&gt; (dumbphone, timer safe, Brick’s NFC tag)&lt;/td&gt;
      &lt;td&gt;Everything on the device you left behind&lt;/td&gt;
      &lt;td&gt;Every other screen in the building&lt;/td&gt;
      &lt;td&gt;Physically retrieving the object&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;People whose problem is one hour in one place: writing sessions, dinners, sleep&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Grayscale and friction&lt;/strong&gt; (Color Filters, Focus modes, apps off the Home Screen)&lt;/td&gt;
      &lt;td&gt;Nothing; it only makes the phone duller and slower to reach&lt;/td&gt;
      &lt;td&gt;Anything, if you actually want it&lt;/td&gt;
      &lt;td&gt;Three taps in Settings, or Spotlight&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;Drift more than compulsion: the person who opens an app for no reason and stays for 40 minutes&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Two notes on that table. A DNS filter is the only row that touches apps you did not list, which makes it the right tool for adult-content blocking and the wrong tool for “keep me off X between 9 and 5.” And Apple’s own review rules constrain the VPN row: &lt;a href=&quot;https://developer.apple.com/app-store/review/guidelines/&quot;&gt;App Store Review Guideline 5.4&lt;/a&gt; requires VPN apps to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NEVPNManager&lt;/code&gt; and to come from a developer enrolled as an organisation, and the content-filter entitlement is granted case by case, which is why so few of these exist.&lt;/p&gt;

&lt;h2 id=&quot;can-an-app-block-instagram-on-iphone&quot;&gt;Can an app block Instagram on iPhone?&lt;/h2&gt;

&lt;p&gt;Yes, with three caveats that matter more than the yes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The app, properly.&lt;/strong&gt; Select Instagram in the picker, put the token in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;store.shield.applications&lt;/code&gt;, and tapping the icon shows a shield instead of launching the app. The app does not open in the background, does not refresh, does not get its five seconds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The website, mostly.&lt;/strong&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ShieldSettings.webDomains&lt;/code&gt; covers Safari. Selecting web content in the picker is what makes instagram.com in Safari behave the same way as the app. Coverage inside third-party browsers and in-app web views is less predictable, and I would not build a plan around it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not the notifications.&lt;/strong&gt; A shield stops a launch. It does not stop delivery. If a badge and a banner are what pull you in, the shield fixes the wrong half of the loop, and a Focus mode is the better tool, or the two together.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not your other screens.&lt;/strong&gt; The store is local to the device. Your iPad, your Mac, and the work laptop are all untouched. Family Controls does not ship on macOS in a form that supports this mechanic, so any shield app that does cover the Mac uses a different mechanism there.&lt;/p&gt;

&lt;h2 id=&quot;is-there-an-app-blocker-that-cannot-be-bypassed&quot;&gt;Is there an app blocker that cannot be bypassed?&lt;/h2&gt;

&lt;p&gt;No, not on a device you own and control, and that is deliberate. If a third-party app could permanently restrict your phone, the first malicious app to ship would brick a lot of phones, so Apple keeps the exit in your hands.&lt;/p&gt;

&lt;p&gt;There is always a way out. The useful question is how long it takes and whether the effort lands somewhere useful. Here is the ladder, cheapest first.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Way out&lt;/th&gt;
      &lt;th&gt;Roughly how long&lt;/th&gt;
      &lt;th&gt;What it costs you&lt;/th&gt;
      &lt;th&gt;Can the app tell?&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Tap-through or “I really need this” button, if the app ships one&lt;/td&gt;
      &lt;td&gt;1 to 2 taps, under 5 seconds&lt;/td&gt;
      &lt;td&gt;Nothing&lt;/td&gt;
      &lt;td&gt;Yes, it fired the action&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Wait out a timer or a breathing pause&lt;/td&gt;
      &lt;td&gt;5 to 60 seconds&lt;/td&gt;
      &lt;td&gt;Attention, the currency you were defending&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Solve a gate: a math problem, a long typed phrase&lt;/td&gt;
      &lt;td&gt;20 to 60 seconds&lt;/td&gt;
      &lt;td&gt;Concentration, which is the point&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Delete the blocker&lt;/td&gt;
      &lt;td&gt;~10 seconds, unless &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;denyAppRemoval&lt;/code&gt; is set&lt;/td&gt;
      &lt;td&gt;Your settings, history, streak&lt;/td&gt;
      &lt;td&gt;No, it is gone&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Revoke Family Controls in Settings&lt;/td&gt;
      &lt;td&gt;~15 seconds if you know the path&lt;/td&gt;
      &lt;td&gt;Every shield drops at once; tokens are voided&lt;/td&gt;
      &lt;td&gt;Yes, &lt;a href=&quot;https://developer.apple.com/documentation/familycontrols/authorizationcenter/authorizationstatus&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;authorizationStatus&lt;/code&gt;&lt;/a&gt; is observable&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Turn off Screen Time entirely&lt;/td&gt;
      &lt;td&gt;~20 seconds&lt;/td&gt;
      &lt;td&gt;Your limits and your usage history&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Erase and restore the device&lt;/td&gt;
      &lt;td&gt;30+ minutes&lt;/td&gt;
      &lt;td&gt;Everything&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Someone else holds the Screen Time passcode&lt;/td&gt;
      &lt;td&gt;Not available to you&lt;/td&gt;
      &lt;td&gt;Autonomy, a real cost and sometimes worth paying&lt;/td&gt;
      &lt;td&gt;N/A&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Two rows need comment. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ApplicationSettings.denyAppRemoval&lt;/code&gt; is real: a blocker can prevent app deletion device-wide, which closes the cheapest exit. And revocation is observable, so an app can watch its own authorisation status and know the moment you walked out. Whether it should do anything with that beyond recording it for you is a design question with an obvious wrong answer.&lt;/p&gt;

&lt;p&gt;Read down that ladder and “unbypassable” stops meaning anything. What varies is how many seconds sit between the impulse and the app, and whether those seconds buy you anything.&lt;/p&gt;

&lt;h2 id=&quot;what-the-api-reality-means-for-design&quot;&gt;What the API reality means for design&lt;/h2&gt;

&lt;p&gt;I wrote a while ago that &lt;a href=&quot;/journal/unlock-cost-outside-the-app/&quot;&gt;the unlock cost has to live outside the app&lt;/a&gt;: a cost you set yourself, inside the software, is a cost your craving can renegotiate in the middle of the craving. The API facts above make the same argument at the level of the platform. Revocation is always about fifteen seconds away, so the wall is not the product. The price is.&lt;/p&gt;

&lt;p&gt;And the price should be paid somewhere your future self benefits. Waiting fails that test: you pay in attention, which is exactly what you were trying to protect, and you get nothing back. Body movement passes it, because the cost lands in the rest of your life.&lt;/p&gt;

&lt;p&gt;The other designs are not wrong for that. Several are good for problems mine does not solve:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;/alternatives/one-sec/&quot;&gt;one sec&lt;/a&gt;&lt;/strong&gt; interrupts &lt;em&gt;before&lt;/em&gt; the app opens, with a breath, a pause or a question. If your thumb arrives before your intention does, that suits you better than a hard gate, because it targets the reflex. A gate you have already earned your way past does nothing about a reflex. one sec also runs on Android, which nothing of ours does.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;/alternatives/brick/&quot;&gt;Brick&lt;/a&gt;&lt;/strong&gt; puts a physical NFC tag in the loop, around $59 one time. Leaving the tag at home is a commitment you cannot undo from the couch, and it is the only design in the category where the friction is made of atoms instead of software you authorised. The cost is an object to buy, carry, and lose. &lt;a href=&quot;/alternatives/unpluq/&quot;&gt;Unpluq&lt;/a&gt; works on the same physical principle, paired with a subscription.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;/alternatives/screenzen/&quot;&gt;ScreenZen&lt;/a&gt;&lt;/strong&gt; is free, with escalating pauses, and being free is a real advantage that EarnLock’s $19.99 lifetime tier does not erase. &lt;strong&gt;&lt;a href=&quot;/alternatives/opal/&quot;&gt;Opal&lt;/a&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;a href=&quot;/alternatives/jomo/&quot;&gt;Jomo&lt;/a&gt;&lt;/strong&gt; are more polished than we are, and Jomo covers iPhone, iPad, and Mac.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/apps/earnlock/&quot;&gt;EarnLock&lt;/a&gt; uses exactly the same three frameworks as all of them and does nothing Apple does not publish. What it changes is the price: your selected apps stay shielded until you hit a daily activity goal read from Apple Health (steps in the free tier, active minutes or active energy in Premium). The shield is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ShieldConfiguration&lt;/code&gt; extension that paints a live progress ring with the number remaining, where Apple’s version shows a generic restriction screen. &lt;em&gt;3,412 steps until unlock&lt;/em&gt; tells you where you’re going; &lt;em&gt;This app has been restricted&lt;/em&gt; just stops you. The Apple Watch app reads HealthKit on the wrist, so the count keeps running on a walk without the phone. Which number to set is its own question, covered in &lt;a href=&quot;/journal/how-many-steps-a-day-to-aim-for/&quot;&gt;what the step-count studies support&lt;/a&gt;. $1.99/month, $9.99/year, or $19.99 once, each price checked in August 2026.&lt;/p&gt;

&lt;p&gt;EarnLock has the same constraints as everything else on this page. It cannot see which apps you blocked either. It does not stop notifications. It is iPhone and Apple Watch only, with no iPad or Mac version, because the framework does not support the mechanic there. It ships one math-gated emergency unlock per day, on purpose, because people delete a tool with no exit. And if you open Settings and revoke its authorisation, every shield drops and it can do nothing about that. The same is true of every Family Controls app named on this page, and worth knowing before you pay any of us. (The data rules behind that, and behind every other Lagerland app, are on the &lt;a href=&quot;/transparency/&quot;&gt;transparency page&lt;/a&gt;.)&lt;/p&gt;

&lt;h2 id=&quot;tldr&quot;&gt;TL;DR&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;No third-party iPhone app blocks anything itself.&lt;/strong&gt; It asks iOS to, via FamilyControls (permission and the picker), ManagedSettings (the shield), and DeviceActivity (schedules and thresholds).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The picker returns opaque tokens, not app names.&lt;/strong&gt; Your blocker cannot log, sell, or leak which apps you chose, because iOS never gives it the names. The same rule stops it from pre-filling a recommended list for you.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;A shield blocks launching, not notifying.&lt;/strong&gt; It covers the app and, via web domains, Safari. It does not cover your iPad, your Mac, or the banner that pulled you in.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Nothing is unbypassable, by Apple’s design.&lt;/strong&gt; Revoking Family Controls in Settings takes about fifteen seconds and voids every shield at once. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;denyAppRemoval&lt;/code&gt; closes the cheapest exit; nothing closes the last one.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;So compare the price, not the wall.&lt;/strong&gt; What varies is what stands between the impulse and the app (a tap, a wait, a physical tag, or a step count) and whether paying it leaves you better off.&lt;/li&gt;
&lt;/ul&gt;
</content>
  </entry>

  <entry>
    <title>How to compress a video for email: the size limits and the bitrate math</title>
    <link href="https://lagerland-apps.github.io/journal/compress-a-video-for-email/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/compress-a-video-for-email/</id>
    <published>2026-07-25T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Every email provider caps what it will carry, and video reaches the cap fast. This post covers the limits Gmail, Outlook and iCloud Mail publish, why a 25 MB limit does not take a 25 MB file, the arithmetic that turns a target size into a bitrate, and how MediaKit does that arithmetic on iPhone or Mac without uploading the clip.</summary>
    <content type="html">&lt;p&gt;At the 8 Mbps that YouTube recommends for 1080p uploads, one minute of video is 60 MB. That is more than twice what Gmail will attach. Getting a clip into an email is a small sum: pick a target below your provider’s limit, work out the bitrate that fits it, and re-encode at that bitrate. This post gives the numbers for each step, then shows how &lt;a href=&quot;/apps/mediakit/&quot;&gt;MediaKit&lt;/a&gt; does it on iPhone and Mac without sending the clip anywhere first.&lt;/p&gt;

&lt;h2 id=&quot;how-big-a-video-can-you-email&quot;&gt;How big a video can you email?&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Service&lt;/th&gt;
      &lt;th&gt;Limit&lt;/th&gt;
      &lt;th&gt;What it counts&lt;/th&gt;
      &lt;th&gt;Over the limit&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Gmail, personal account&lt;/td&gt;
      &lt;td&gt;25 MB&lt;/td&gt;
      &lt;td&gt;All attachments in the message together&lt;/td&gt;
      &lt;td&gt;Gmail replaces the attachment with a Google Drive link&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Outlook app, internet accounts such as Outlook.com&lt;/td&gt;
      &lt;td&gt;20 MB&lt;/td&gt;
      &lt;td&gt;The attachments plus the email itself&lt;/td&gt;
      &lt;td&gt;Microsoft suggests compressing, or sharing a cloud link&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Exchange, work accounts&lt;/td&gt;
      &lt;td&gt;10 MB by default&lt;/td&gt;
      &lt;td&gt;The whole message; administrators can change it&lt;/td&gt;
      &lt;td&gt;As above&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;iCloud Mail&lt;/td&gt;
      &lt;td&gt;20 MB&lt;/td&gt;
      &lt;td&gt;Incoming and outgoing messages&lt;/td&gt;
      &lt;td&gt;Up to 5 GB with Mail Drop turned on&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Mail Drop (Apple Mail, iCloud Mail)&lt;/td&gt;
      &lt;td&gt;5 GB&lt;/td&gt;
      &lt;td&gt;The message including attachments; each link expires after 30 days&lt;/td&gt;
      &lt;td&gt;Mail Drop can’t send it&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Limits as each provider’s help page stated them in July 2026: &lt;a href=&quot;https://support.google.com/mail/answer/6584&quot;&gt;Gmail Help&lt;/a&gt;, &lt;a href=&quot;https://support.microsoft.com/en-us/office/send-large-files-with-outlook-8c698842-b462-4a4c-8d53-5c5dd04f77ef&quot;&gt;Microsoft Support&lt;/a&gt;, and Apple’s pages on &lt;a href=&quot;https://support.apple.com/en-us/102198&quot;&gt;iCloud Mail limits&lt;/a&gt; and &lt;a href=&quot;https://support.apple.com/en-us/108329&quot;&gt;Mail Drop&lt;/a&gt;. Work and school accounts can be set lower by their administrators, and the receiving server applies its own limit. Microsoft’s &lt;a href=&quot;https://learn.microsoft.com/en-us/exchange/mail-flow/message-size-limits&quot;&gt;Exchange documentation&lt;/a&gt; says a message must fit the limits of both sender and recipient, so the smallest limit on the route decides.&lt;/p&gt;

&lt;h2 id=&quot;why-a-25-mb-limit-does-not-take-a-25-mb-file&quot;&gt;Why a 25 MB limit does not take a 25 MB file&lt;/h2&gt;

&lt;p&gt;Email is a text format. Before a video can travel as an attachment it is Base64-encoded: every three bytes of the file become four characters of text, broken into lines of at most 76 characters (&lt;a href=&quot;https://www.rfc-editor.org/rfc/rfc2045#section-6.8&quot;&gt;RFC 2045, section 6.8&lt;/a&gt;). The message that crosses the network is about a third larger than the file on your disk.&lt;/p&gt;

&lt;p&gt;Whether a limit is measured before or after that encoding varies, and consumer help pages rarely say. Microsoft’s Exchange documentation does: Base64 adds about 33%, so a 64 MB message limit means a realistic maximum of about 48 MB. Its Outlook page adds that the 20 MB limit includes the email, not just the attachment.&lt;/p&gt;

&lt;p&gt;So the working rule is three-quarters of the stated limit:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Stated limit&lt;/th&gt;
      &lt;th&gt;Aim for a file of about&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;25 MB (Gmail)&lt;/td&gt;
      &lt;td&gt;18 MB&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;20 MB (Outlook, iCloud Mail)&lt;/td&gt;
      &lt;td&gt;15 MB&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;10 MB (Exchange default)&lt;/td&gt;
      &lt;td&gt;7.5 MB&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Undershooting costs a little picture quality. Overshooting means a bounce, or a link where you wanted an attachment.&lt;/p&gt;

&lt;h2 id=&quot;how-to-work-out-the-bitrate-that-fits&quot;&gt;How to work out the bitrate that fits&lt;/h2&gt;

&lt;p&gt;File size is bitrate multiplied by duration. Run it backwards:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Convert the target to kilobits.&lt;/strong&gt; Megabytes × 8,000, counting a megabyte as 1,000,000 bytes.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Divide by the clip’s length in seconds.&lt;/strong&gt; That is the total bitrate in kbps.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Subtract the audio.&lt;/strong&gt; 128 kbps is a common stereo setting; 64 kbps is plenty for speech.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The rest is the video bitrate.&lt;/strong&gt; Leave a few percent for the container’s own overhead.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A 90-second clip for Gmail: 18 MB × 8,000 = 144,000 kilobits. Divided by 90 seconds, that is 1,600 kbps. Take away 128 kbps of audio and about 1,470 kbps is left for the picture.&lt;/p&gt;

&lt;p&gt;The same sum for common lengths, with 128 kbps of audio taken out first:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Clip length&lt;/th&gt;
      &lt;th&gt;7.5 MB file&lt;/th&gt;
      &lt;th&gt;15 MB file&lt;/th&gt;
      &lt;th&gt;18 MB file&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;30 seconds&lt;/td&gt;
      &lt;td&gt;1,870 kbps&lt;/td&gt;
      &lt;td&gt;3,870 kbps&lt;/td&gt;
      &lt;td&gt;4,670 kbps&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;1 minute&lt;/td&gt;
      &lt;td&gt;870 kbps&lt;/td&gt;
      &lt;td&gt;1,870 kbps&lt;/td&gt;
      &lt;td&gt;2,270 kbps&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2 minutes&lt;/td&gt;
      &lt;td&gt;370 kbps&lt;/td&gt;
      &lt;td&gt;870 kbps&lt;/td&gt;
      &lt;td&gt;1,070 kbps&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;5 minutes&lt;/td&gt;
      &lt;td&gt;70 kbps&lt;/td&gt;
      &lt;td&gt;270 kbps&lt;/td&gt;
      &lt;td&gt;350 kbps&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Figures are rounded down.&lt;/p&gt;

&lt;h2 id=&quot;which-resolution-and-codec-to-choose&quot;&gt;Which resolution and codec to choose&lt;/h2&gt;

&lt;p&gt;A bitrate is only generous or thin relative to the frame it has to fill. For scale, YouTube’s &lt;a href=&quot;https://support.google.com/youtube/answer/1722171&quot;&gt;recommended upload settings&lt;/a&gt; for standard frame rates ask for 8 Mbps at 1080p, 5 Mbps at 720p, 2.5 Mbps at 480p and 1 Mbps at 360p. Those figures are high, because YouTube re-encodes everything it receives, but they show how fast the need falls with frame size: 1080p has 2.25 times the pixels of 720p.&lt;/p&gt;

&lt;p&gt;A rough rule: if your video budget is well under half of YouTube’s figure for the clip’s resolution, step down one resolution. By that rule, a one-minute clip at 18 MB (2,270 kbps) sits better at 720p than at 1080p, and at 7.5 MB (870 kbps) it belongs at 480p or below. Three other settings move the result:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Audio bitrate.&lt;/strong&gt; For a talking-head clip, 64 kbps instead of 128 kbps hands the difference to the picture. On a five-minute clip at 15 MB, that is nearly a quarter more video bitrate.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Frame rate.&lt;/strong&gt; A 60 fps clip spreads its bits across twice as many frames as a 30 fps one. YouTube’s figures for 48 to 60 fps are about half as high again as for 24 to 30.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Codec.&lt;/strong&gt; Apple says &lt;a href=&quot;https://support.apple.com/en-us/116944&quot;&gt;HEVC compresses better than H.264&lt;/a&gt;, and recent Apple devices play it. But you don’t control where the attachment is opened, and H.264 in an MP4 plays almost everywhere. Apple’s page also notes that its devices &lt;em&gt;might&lt;/em&gt; convert HEVC to H.264 when sharing to a device that can’t play it; for a file you have already compressed, it is simpler to pick H.264 yourself.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;when-to-send-a-link-instead&quot;&gt;When to send a link instead&lt;/h2&gt;

&lt;p&gt;The five-minute row of the table is where compression stops being useful: 270 kbps is about a quarter of what YouTube suggests for 360p. When the budget falls that low, a link serves the recipient better than an attachment.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Mail Drop&lt;/strong&gt; in Apple Mail and iCloud Mail sends files up to 5 GB as a download link that expires after 30 days. Mail offers it when a message is larger than your provider allows.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Gmail&lt;/strong&gt; swaps an attachment over 25 MB for a Google Drive link on its own.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Outlook&lt;/strong&gt; points you to compressing the file or sharing it from cloud storage.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With a link, the recipient gets the full-quality original, and a copy sits on a server for as long as the link lives.&lt;/p&gt;

&lt;h2 id=&quot;doing-it-in-mediakit&quot;&gt;Doing it in MediaKit&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/apps/mediakit/&quot;&gt;MediaKit&lt;/a&gt; runs the arithmetic above on the device, on iPhone and on Mac, and never uploads the clip. Video Compress is one of the five tools that stay free after the three-day trial.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Open the clip.&lt;/strong&gt; On a Mac, drag it onto the window. On iPhone, add it from Photos or Files, or send it from another app’s share sheet.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Choose the video Compress tool&lt;/strong&gt; and set &lt;strong&gt;Mode&lt;/strong&gt; to &lt;strong&gt;Target size&lt;/strong&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Type the target&lt;/strong&gt; from the three-quarters table, for example 18, with the unit on MB. MediaKit counts a megabyte as 1,000,000 bytes.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Open Advanced.&lt;/strong&gt; Set &lt;strong&gt;Max resolution&lt;/strong&gt; using the bitrate table, leave &lt;strong&gt;Codec&lt;/strong&gt; on H.264 for email, and choose &lt;strong&gt;64 kbps (voice)&lt;/strong&gt; under &lt;strong&gt;Audio bitrate&lt;/strong&gt; if the clip is mostly speech.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Run it, then check the size&lt;/strong&gt; of the result before you attach it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In Target size mode MediaKit does steps one to four of the sum itself: it divides the target by the clip’s length, takes out the audio bitrate you chose and holds back 3%, encodes, then measures the file it wrote and encodes again with a corrected bitrate if it missed. A 4K or 1440p source starts with Max resolution set to 1080p; for a small target, set it lower.&lt;/p&gt;

&lt;p&gt;If you already use HandBrake for this job, the &lt;a href=&quot;/alternatives/handbrake/&quot;&gt;HandBrake comparison&lt;/a&gt; covers where the two differ, and the &lt;a href=&quot;/alternatives/compress-videos-resize-video/&quot;&gt;Compress Videos &amp;amp; Resize Video comparison&lt;/a&gt; does the same on iPhone. Why the studio keeps this work off other people’s servers is the subject of &lt;a href=&quot;/journal/your-photos-shouldnt-ride-the-elevator/&quot;&gt;an earlier post&lt;/a&gt;, and the wider toolkit is in &lt;a href=&quot;/journal/every-media-tool-already-on-your-mac/&quot;&gt;this one&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>App Store proceeds vs sales: what each money column in App Store Connect means</title>
    <link href="https://lagerland-apps.github.io/journal/app-store-proceeds-vs-sales/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/app-store-proceeds-vs-sales/</id>
    <published>2026-07-20T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Sales and Trends shows two money figures side by side, and only one of them is close to what reaches your bank. This is a reference to what each number in App Store Connect&apos;s sales reports counts, how Apple gets from the customer&apos;s price to your proceeds, and why neither will match the payment to the cent.</summary>
    <content type="html">&lt;p&gt;Sales is what customers paid. Proceeds is what you keep. In Apple’s own words, proceeds are “the Customer Price minus applicable taxes and Apple’s commission” (&lt;a href=&quot;https://developer.apple.com/help/app-store-connect/view-sales-and-trends/view-units-proceeds-sales-and-pre-orders/&quot;&gt;Apple&lt;/a&gt;). Below: which column holds which figure, which rate applies, and why the totals move from one report to the next.&lt;/p&gt;

&lt;h2 id=&quot;what-does-each-number-in-app-store-connect-mean&quot;&gt;What does each number in App Store Connect mean?&lt;/h2&gt;

&lt;p&gt;Paraphrasing Apple’s definitions for &lt;a href=&quot;https://developer.apple.com/help/app-store-connect/view-sales-and-trends/view-units-proceeds-sales-and-pre-orders/&quot;&gt;Sales and Trends&lt;/a&gt;, the &lt;a href=&quot;https://developer.apple.com/help/app-store-connect/reference/summary-sales-report&quot;&gt;Summary Sales Report&lt;/a&gt; and the &lt;a href=&quot;https://developer.apple.com/help/app-store-connect/reference/financial-report-fields/&quot;&gt;financial reports&lt;/a&gt;:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Term&lt;/th&gt;
      &lt;th&gt;Where it appears&lt;/th&gt;
      &lt;th&gt;What it counts&lt;/th&gt;
      &lt;th&gt;Tax included&lt;/th&gt;
      &lt;th&gt;Commission removed&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Units&lt;/td&gt;
      &lt;td&gt;Sales and Trends, Sales report&lt;/td&gt;
      &lt;td&gt;First-time purchases of an app or bundle, plus In-App Purchases. Sales and Trends leaves out updates and redownloads unless you filter them in. Refunds count as negative units&lt;/td&gt;
      &lt;td&gt;n/a&lt;/td&gt;
      &lt;td&gt;n/a&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Sales&lt;/td&gt;
      &lt;td&gt;Sales and Trends&lt;/td&gt;
      &lt;td&gt;The total billed to customers for apps, bundles and In-App Purchases&lt;/td&gt;
      &lt;td&gt;Yes, taxes Apple collects and remits&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Proceeds&lt;/td&gt;
      &lt;td&gt;Sales and Trends&lt;/td&gt;
      &lt;td&gt;What you earn on those sales, as an estimate until the financial reports close&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Customer Price&lt;/td&gt;
      &lt;td&gt;Sales report&lt;/td&gt;
      &lt;td&gt;The price per unit billed to the customer; negative on refund rows&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Developer Proceeds&lt;/td&gt;
      &lt;td&gt;Sales report&lt;/td&gt;
      &lt;td&gt;What you receive per unit; stays positive on refund rows&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Partner Share&lt;/td&gt;
      &lt;td&gt;Financial reports&lt;/td&gt;
      &lt;td&gt;Final proceeds per unit&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Extended Partner Share&lt;/td&gt;
      &lt;td&gt;Financial reports&lt;/td&gt;
      &lt;td&gt;Quantity multiplied by Partner Share&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;In the downloadable report, both money columns are per unit, which is easy to miss. Apple’s sample row has 100 universal app purchases in the United States, where “Customers paid .99 USD for each unit and you received .70 USD for each” (&lt;a href=&quot;https://developer.apple.com/help/app-store-connect/reference/summary-sales-report&quot;&gt;Apple&lt;/a&gt;). That row is 99.00 USD of sales and 70.00 USD of proceeds. Add up the Developer Proceeds column without multiplying by Units and a busy app’s revenue shrinks to a fraction of itself.&lt;/p&gt;

&lt;h2 id=&quot;how-does-a-customer-price-turn-into-proceeds&quot;&gt;How does a customer price turn into proceeds?&lt;/h2&gt;

&lt;p&gt;Per unit, the order of operations is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Developer Proceeds = (Customer Price − tax included in it) × your proceeds rate&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Apple’s subscription terms spell out the order: you receive 70% of the price “minus applicable taxes”, or 85% once the higher rate applies (&lt;a href=&quot;https://developer.apple.com/app-store/subscriptions/&quot;&gt;Apple&lt;/a&gt;). Tax comes off first, and the rate applies to what is left.&lt;/p&gt;

&lt;p&gt;A rough example for a 4.99 EUR price in Germany, where the price includes 19% VAT:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Step&lt;/th&gt;
      &lt;th&gt;Standard rate&lt;/th&gt;
      &lt;th&gt;Small Business Program or subscription year two&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Customer Price&lt;/td&gt;
      &lt;td&gt;4.99&lt;/td&gt;
      &lt;td&gt;4.99&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Price without 19% VAT&lt;/td&gt;
      &lt;td&gt;4.19&lt;/td&gt;
      &lt;td&gt;4.19&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Proceeds rate&lt;/td&gt;
      &lt;td&gt;70%&lt;/td&gt;
      &lt;td&gt;85%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Developer Proceeds, about&lt;/td&gt;
      &lt;td&gt;2.94&lt;/td&gt;
      &lt;td&gt;3.56&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;That is my arithmetic, not Apple’s figure. Apple works out proceeds for each storefront from its own price points and tax rules, so the real figure can be a cent or two off. The same price point earns different proceeds in different countries because the tax inside the price differs, and Apple notes that it “may need to adjust prices or your proceeds due to changes in tax regulations or foreign exchange rates” (&lt;a href=&quot;https://developer.apple.com/news?id=y3w8ck7j&quot;&gt;Apple&lt;/a&gt;).&lt;/p&gt;

&lt;h2 id=&quot;what-commission-rates-does-apple-charge&quot;&gt;What commission rates does Apple charge?&lt;/h2&gt;

&lt;p&gt;Under Apple’s standard App Store terms:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Situation&lt;/th&gt;
      &lt;th&gt;Commission&lt;/th&gt;
      &lt;th&gt;You keep&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Standard rate on paid apps and In-App Purchases&lt;/td&gt;
      &lt;td&gt;30%&lt;/td&gt;
      &lt;td&gt;70%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;App Store Small Business Program member&lt;/td&gt;
      &lt;td&gt;15%&lt;/td&gt;
      &lt;td&gt;85%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Auto-renewable subscription, first year of a subscriber’s paid service&lt;/td&gt;
      &lt;td&gt;30%&lt;/td&gt;
      &lt;td&gt;70%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Auto-renewable subscription after one year of paid service&lt;/td&gt;
      &lt;td&gt;15%&lt;/td&gt;
      &lt;td&gt;85%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Any subscription, Small Business Program member&lt;/td&gt;
      &lt;td&gt;15%&lt;/td&gt;
      &lt;td&gt;85%&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The &lt;a href=&quot;https://developer.apple.com/app-store/small-business-program/&quot;&gt;Small Business Program&lt;/a&gt; is for developers who, together with any associated developer accounts, earned no more than 1 million USD in proceeds in the previous calendar year and stay under it in the current one. You have to enrol; it isn’t automatic. Apple adjusts proceeds fifteen days after the end of the fiscal month in which it approves you. Cross the threshold during a year and the standard rate applies to future sales.&lt;/p&gt;

&lt;p&gt;For subscriptions, the 85% rate follows days of paid service, counted per subscription group (&lt;a href=&quot;https://developer.apple.com/app-store/subscriptions/&quot;&gt;Apple&lt;/a&gt;). Free trials don’t count toward the year; paid introductory offers do. If a subscription lapses and the customer comes back within 60 days, the count resumes. After 60 days it starts again. In the Sales report, rows earning the higher rate carry Rate After One Year in the Proceeds Reason column.&lt;/p&gt;

&lt;p&gt;These are the standard terms. Storefronts in &lt;a href=&quot;https://developer.apple.com/support/app-distribution-in-japan/&quot;&gt;Japan&lt;/a&gt; and the &lt;a href=&quot;https://developer.apple.com/support/dma-and-apps-in-the-eu/&quot;&gt;European Union&lt;/a&gt; run under separate Apple business terms with their own rate tables, and Apple has changed both since 2024. If a large share of your sales comes from either, check those pages before modelling proceeds with the percentages above.&lt;/p&gt;

&lt;h2 id=&quot;where-does-tax-come-out&quot;&gt;Where does tax come out?&lt;/h2&gt;

&lt;p&gt;Apple’s definition of Customer Price says it is “inclusive of any applicable taxes we collect and remit” (&lt;a href=&quot;https://developer.apple.com/help/app-store-connect/reference/summary-sales-report&quot;&gt;Apple&lt;/a&gt;). So sales, built from Customer Price, includes that tax, and proceeds never do. When you compare two storefronts at the same price, the one with the higher VAT or GST pays you less.&lt;/p&gt;

&lt;p&gt;Income tax and withholding are a separate layer. They don’t appear in Sales and Trends at all. Financial reports carry a Taxes and Adjustments field, and Apple applies any withholding tax when it makes a payment (&lt;a href=&quot;https://developer.apple.com/help/app-store-connect/getting-paid/view-payments-and-proceeds&quot;&gt;Apple&lt;/a&gt;).&lt;/p&gt;

&lt;h2 id=&quot;how-do-refunds-show-up&quot;&gt;How do refunds show up?&lt;/h2&gt;

&lt;p&gt;In the Sales report, a refund row has negative Units and a negative Customer Price, while Developer Proceeds stays positive (&lt;a href=&quot;https://developer.apple.com/help/app-store-connect/reference/summary-sales-report&quot;&gt;Apple&lt;/a&gt;). Multiply proceeds by units, as you do for every row, and the refund subtracts itself. A Units value of 0 can mean a partial refund.&lt;/p&gt;

&lt;p&gt;Sales and Trends folds processed refunds into its daily unit totals and shows them as negative units; to see the refund count on its own, add a filter. A refund appears on the day Apple processes it, which is rarely the day of the original purchase, so a quiet day can show negative proceeds.&lt;/p&gt;

&lt;h2 id=&quot;why-doesnt-sales-and-trends-match-payments-and-financial-reports&quot;&gt;Why doesn’t Sales and Trends match Payments and Financial Reports?&lt;/h2&gt;

&lt;p&gt;Apple’s short answer is that Sales and Trends provides next-day data, while Payments and Financial Reports provide final proceeds (&lt;a href=&quot;https://developer.apple.com/help/app-store-connect/view-sales-and-trends/download-and-view-reports&quot;&gt;Apple&lt;/a&gt;). The reasons underneath, from Apple’s page on &lt;a href=&quot;https://developer.apple.com/help/app-store-connect/measure-app-performance/differences-in-reporting-tools&quot;&gt;differences in reporting tools&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Sales and Trends records a transaction when the customer starts it. Financial reports include only settled transactions where Apple collected the payment, so a purchase late in one month can land in the next fiscal month, and a payment Apple never collects never appears.&lt;/li&gt;
  &lt;li&gt;Financial reports follow Apple’s fiscal calendar, whose months run Sunday to Saturday and don’t line up with calendar months. Sales and Trends reports use Pacific Time days.&lt;/li&gt;
  &lt;li&gt;Sales and Trends estimates USD amounts from a rolling average of the previous month’s exchange rates. Financial reports use the rate that converts each currency to your bank account’s currency.&lt;/li&gt;
  &lt;li&gt;Taxes, adjustments and withholding appear only on the financial side.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use Sales and Trends to see direction: which app sold, in which country, this week against last. Use the financial reports when the number has to match a bank statement.&lt;/p&gt;

&lt;h2 id=&quot;where-appmeta-pulse-fits&quot;&gt;Where AppMeta Pulse fits&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/apps/appmeta-pulse/&quot;&gt;AppMeta Pulse&lt;/a&gt; is the iPhone dashboard I built for the daily look at these numbers. It downloads the daily Sales report and the subscription reports through the App Store Connect API with a key you create, and keeps Apple’s names for things. The main amount is Proceeds by default, described in the app as Apple’s payout after commission; in Settings, under Display, you can switch it to Sales, the full customer price. Refunds are counted from rows with negative units. Each row is converted from its own currency into the display currency you pick, using the European Central Bank’s monthly average rates.&lt;/p&gt;

&lt;p&gt;Pulse reads Sales and Trends, not Payments and Financial Reports. Its figures are next-day numbers with the same caveats as the Sales and Trends page itself. For subscription revenue on a monthly footing, the earlier post on &lt;a href=&quot;/journal/how-to-calculate-mrr-for-app-store-subscriptions/&quot;&gt;calculating MRR from the Subscription report&lt;/a&gt; covers the formula, and &lt;a href=&quot;/journal/read-only-revenue-on-the-iphone/&quot;&gt;this post&lt;/a&gt; explains why a quick revenue check belongs on the phone.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>The same Wikipedia article is a different article in another language</title>
    <link href="https://lagerland-apps.github.io/journal/wikipedia-is-different-in-every-language/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/wikipedia-is-different-in-every-language/</id>
    <published>2026-07-16T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">The languages sidebar on a Wikipedia article looks like a language switcher, but each language Wikipedia is an independent encyclopedia with its own editors, its own inclusion rules, and its own article set. Two editions can disagree about facts, framing, length, and whether a subject merits an article at all. This post covers what differs, how big each edition really is, and why reading a topic in two languages is a real research technique.</summary>
    <content type="html">&lt;p&gt;Open the English article about a Finnish lake and click Suomi in the languages sidebar. You will probably not get that article in Finnish. You will get a different article, longer and differently sourced, with several paragraphs on fishing rights and local place-name history that English never had, and without the geology section you came for.&lt;/p&gt;

&lt;p&gt;The sidebar looks like a language switcher, and every other website has trained you to read it that way: same page, different words. On Wikipedia it is a list of independent encyclopedias that each happen to have an article about the same subject.&lt;/p&gt;

&lt;p&gt;Most questions people have about Wikipedia and languages are answered once that misreading is cleared up, so start there.&lt;/p&gt;

&lt;h2 id=&quot;are-wikipedia-articles-translated-into-other-languages&quot;&gt;Are Wikipedia articles translated into other languages?&lt;/h2&gt;

&lt;p&gt;Usually not. Each language Wikipedia is a separate project with its own editors, administrators, notability rules, sourcing norms, deletion process, and article set. Articles are written locally by people working in that language. There is no English master copy for them to be derived from.&lt;/p&gt;

&lt;p&gt;That has four consequences:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;The languages sidebar links concepts, and says nothing about the text.&lt;/strong&gt; Since 2013 those links have lived centrally in &lt;a href=&quot;https://www.wikidata.org/&quot;&gt;Wikidata&lt;/a&gt;: one Wikidata item groups the pages that are &lt;em&gt;about the same subject&lt;/em&gt; across editions. The item says nothing about their length, structure, sourcing, or agreement.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Translation exists, as a seed for new articles.&lt;/strong&gt; MediaWiki’s &lt;a href=&quot;https://www.mediawiki.org/wiki/Content_translation&quot;&gt;Content Translation&lt;/a&gt; tool lets an editor start a new article from an existing one in another language, and has produced a large cumulative number of articles since 2015 (the running total is on the tool’s own dashboards). It is still small next to the tens of millions of articles across all editions, and a translated article stops being a translation as soon as a local editor works on it, which usually happens right away.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Image policy differs.&lt;/strong&gt; English Wikipedia permits a narrow class of non-free images under its &lt;a href=&quot;https://en.wikipedia.org/wiki/Wikipedia:Non-free_content&quot;&gt;non-free content policy&lt;/a&gt;. Several large editions, German among them, accept none at all. The same subject can have a photograph in one language and, permanently, no image in another.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;So do inclusion thresholds.&lt;/strong&gt; English works from a &lt;a href=&quot;https://en.wikipedia.org/wiki/Wikipedia:Notability&quot;&gt;general notability guideline&lt;/a&gt; built on significant coverage in independent reliable sources. German has its own &lt;a href=&quot;https://de.wikipedia.org/wiki/Wikipedia:Relevanzkriterien&quot;&gt;Relevanzkriterien&lt;/a&gt;, stricter in several areas and the subject of a long-running internal argument about exactly that. Other editions are looser than either. A subject can be notable in one encyclopedia and deleted from the next.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So two editions can disagree about facts, framing, article length, and whether the subject deserves an article at all. That is what independent projects do, and none of it is a defect waiting for repair.&lt;/p&gt;

&lt;h2 id=&quot;how-big-is-each-wikipedia-language-edition&quot;&gt;How big is each Wikipedia language edition?&lt;/h2&gt;

&lt;p&gt;All figures below are heavily rounded and approximate as of 2026. Article counts change every hour; check the live table on Wikimedia’s &lt;a href=&quot;https://meta.wikimedia.org/wiki/List_of_Wikipedias&quot;&gt;List of Wikipedias&lt;/a&gt; for current numbers.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Edition&lt;/th&gt;
      &lt;th&gt;Articles (approx., 2026)&lt;/th&gt;
      &lt;th&gt;What the number hides&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;English (en)&lt;/td&gt;
      &lt;td&gt;~7.0M&lt;/td&gt;
      &lt;td&gt;The largest predominantly human-written corpus; also the default most readers never leave&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Cebuano (ceb)&lt;/td&gt;
      &lt;td&gt;~6M&lt;/td&gt;
      &lt;td&gt;Overwhelmingly machine-generated by one bot (Lsjbot); the total moves as the community deletes batches&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;German (de)&lt;/td&gt;
      &lt;td&gt;~3.0M&lt;/td&gt;
      &lt;td&gt;Strict inclusion rules, comparatively low stub ratio, no non-free images&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;French (fr)&lt;/td&gt;
      &lt;td&gt;~2.7M&lt;/td&gt;
      &lt;td&gt;Broad coverage of francophone Africa and the Caribbean that English thins out fast&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Swedish (sv)&lt;/td&gt;
      &lt;td&gt;~2.6M&lt;/td&gt;
      &lt;td&gt;Large bot-created share, same Lsjbot lineage as Cebuano&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Dutch (nl)&lt;/td&gt;
      &lt;td&gt;~2.2M&lt;/td&gt;
      &lt;td&gt;Very high article count relative to speaker population&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Russian (ru)&lt;/td&gt;
      &lt;td&gt;~2.0M&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Spanish (es)&lt;/td&gt;
      &lt;td&gt;~2.0M&lt;/td&gt;
      &lt;td&gt;Coverage split across two dozen national contexts&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Italian (it)&lt;/td&gt;
      &lt;td&gt;~1.9M&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Polish (pl)&lt;/td&gt;
      &lt;td&gt;~1.6M&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Egyptian Arabic (arz)&lt;/td&gt;
      &lt;td&gt;~1.6M&lt;/td&gt;
      &lt;td&gt;Separate edition from Arabic (ar); heavily bot-assisted&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Chinese (zh)&lt;/td&gt;
      &lt;td&gt;~1.4M&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Japanese (ja)&lt;/td&gt;
      &lt;td&gt;~1.4M&lt;/td&gt;
      &lt;td&gt;Deep domestic coverage, notably in rail, media, and local history&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Ukrainian (uk)&lt;/td&gt;
      &lt;td&gt;~1.3M&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Vietnamese (vi)&lt;/td&gt;
      &lt;td&gt;~1.3M&lt;/td&gt;
      &lt;td&gt;Large historical bot-import share&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Arabic (ar)&lt;/td&gt;
      &lt;td&gt;~1.2M&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Portuguese (pt)&lt;/td&gt;
      &lt;td&gt;~1.1M&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Persian (fa)&lt;/td&gt;
      &lt;td&gt;~1.0M&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Finnish (fi)&lt;/td&gt;
      &lt;td&gt;~600K&lt;/td&gt;
      &lt;td&gt;The size most European editions actually are&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Hindi (hi)&lt;/td&gt;
      &lt;td&gt;~200K&lt;/td&gt;
      &lt;td&gt;Enormous speaker population and a small edition, a recurring pattern&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Two things about that column of numbers.&lt;/p&gt;

&lt;p&gt;First, “article” has a precise and unglamorous definition: a page in the main namespace, not a redirect, containing at least one internal link. A one-sentence stub about a river in the Philippines counts exactly as much as a book-length featured article on quantum chromodynamics. Ranking editions by article count ranks them by a measure that ignores everything you care about.&lt;/p&gt;

&lt;p&gt;Second, edition size does not track speaker population. Dutch has more articles than Arabic; Hindi has a fraction of Finnish. Size tracks how many people chose to write an encyclopedia in that language over twenty years, plus whatever bots ran there.&lt;/p&gt;

&lt;h2 id=&quot;why-do-two-editions-disagree-about-the-same-topic&quot;&gt;Why do two editions disagree about the same topic?&lt;/h2&gt;

&lt;p&gt;The divergences fall into recognisable kinds. The table describes each kind in general terms, since the specifics of any one article change weekly.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Kind of divergence&lt;/th&gt;
      &lt;th&gt;What you actually see&lt;/th&gt;
      &lt;th&gt;Why it happens&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Local-interest depth&lt;/td&gt;
      &lt;td&gt;The home-country edition has six sections and forty references; English has four sentences&lt;/td&gt;
      &lt;td&gt;Editors write about what is near them, and the sources are in the local language&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Contested history and naming&lt;/td&gt;
      &lt;td&gt;Different article titles, different framing, different dates given for when something started&lt;/td&gt;
      &lt;td&gt;Titles and framing are settled inside each community, from that community’s reliable-source pool&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Biography emphasis&lt;/td&gt;
      &lt;td&gt;A national figure gets a long career section at home and a stub abroad, and the sections chosen differ&lt;/td&gt;
      &lt;td&gt;Significance is judged locally, and so is which part of a life is the interesting part&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Science and technical depth&lt;/td&gt;
      &lt;td&gt;Usually English is longest; sometimes it very much is not&lt;/td&gt;
      &lt;td&gt;Depth follows whichever subject community showed up, which is not distributed evenly&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Images&lt;/td&gt;
      &lt;td&gt;A photograph in one language, no image at all in another&lt;/td&gt;
      &lt;td&gt;Non-free content policy is per-edition&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Existence&lt;/td&gt;
      &lt;td&gt;A blue link in one edition, a red link in the next&lt;/td&gt;
      &lt;td&gt;Notability thresholds differ, and deletion discussions are local&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Bot stubs&lt;/td&gt;
      &lt;td&gt;Thousands of near-identical settlement or species articles&lt;/td&gt;
      &lt;td&gt;Some editions ran mass-creation bots; others banned the practice outright&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The contested-history row deserves the most thought. When editions disagree about a border, a war, a name, or a leader, it is rarely because one is careless. Each edition’s editors read a different body of published sources, in a different language, from a different set of institutions, and each edition’s neutrality policy is applied by people inside that source environment. Two well-run editions working honestly from different literatures can land in different places, and you only find that out by reading both.&lt;/p&gt;

&lt;h2 id=&quot;what-happens-when-an-edition-has-very-few-active-editors&quot;&gt;What happens when an edition has very few active editors?&lt;/h2&gt;

&lt;p&gt;Editing capacity is not spread evenly. English Wikipedia’s active-editor count runs in the tens of thousands (live figures on &lt;a href=&quot;https://stats.wikimedia.org/&quot;&gt;Wikimedia Statistics&lt;/a&gt;); most editions are in the hundreds or below, and many have single-digit regulars. Below some point, bot-created stubs dominate the count, errors and vandalism survive longer because fewer eyes pass over each page, and a very small group can shape a large share of the edition.&lt;/p&gt;

&lt;p&gt;The Wikimedia Foundation commissioned and published a &lt;a href=&quot;https://meta.wikimedia.org/wiki/Croatian_Wikipedia_Disinformation_Assessment-2021&quot;&gt;disinformation assessment of the Croatian Wikipedia&lt;/a&gt; in 2021 after a small group of administrators had steered content there for years. The &lt;a href=&quot;https://en.wikipedia.org/wiki/Scots_Wikipedia&quot;&gt;Scots Wikipedia&lt;/a&gt; case in 2020 was a different kind of problem and just as instructive: a single prolific editor had written tens of thousands of articles in a version of Scots that fluent speakers did not recognise, and it went unchallenged for years because almost nobody was reading.&lt;/p&gt;

&lt;p&gt;Both were documented and addressed openly, and neither is a reason to distrust Wikipedia in general. They are a reason to know which edition you are reading. A small edition is thinner, which does not make it worse, but you should be able to see how thin it is.&lt;/p&gt;

&lt;h2 id=&quot;how-do-you-actually-read-a-topic-in-a-second-language&quot;&gt;How do you actually read a topic in a second language?&lt;/h2&gt;

&lt;p&gt;The technique is short:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Start from the article you have&lt;/strong&gt; and open the languages sidebar. Every listed edition is a separately written article about the same concept.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Prefer the edition closest to the subject.&lt;/strong&gt; For a Japanese rail line, a Finnish municipal reform, or a Brazilian composer, the home edition almost always has more, and has it from sources nobody translated.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Let the browser translate the page.&lt;/strong&gt; Safari and Chrome both do full-page translation. You do not need to read the language to find out whether the article is four paragraphs or four screens.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Read the references section even when the prose is machine-translated.&lt;/strong&gt; The source list is often the most useful part: local newspapers, national archives, ministry publications, regional academic presses.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Note where the editions disagree.&lt;/strong&gt; Where two editions differ on a date, a name, or a cause, you have found a place where the published literatures differ.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Do not quote the machine translation.&lt;/strong&gt; It is a reading aid; if a specific claim matters, go to the cited source.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It is unglamorous and it works. It is also the fastest way to notice that the English Wikipedia you have been treating as the encyclopedia is one among roughly 340.&lt;/p&gt;

&lt;h2 id=&quot;why-a-deck-holds-up-better-than-a-feed&quot;&gt;Why a deck holds up better than a feed&lt;/h2&gt;

&lt;p&gt;Everything above is reference. The rest is a design argument, and it is the reason &lt;a href=&quot;/apps/wanderwiki/&quot;&gt;WanderWiki&lt;/a&gt; is a swipe deck and not a scroll.&lt;/p&gt;

&lt;p&gt;A feed ranks items by predicted engagement, has no bottom, and treats you leaving as a failure. Every mechanism follows from that. The ranking input is your behaviour, because behaviour predicts engagement better than anything you would tell it. The list is infinite, because a bottom is an exit. Continuation gets rewarded, because a reason to return tomorrow is worth more than a good session today. I have written about the streak half of that machinery &lt;a href=&quot;/journal/streaks-are-a-debt/&quot;&gt;elsewhere&lt;/a&gt;, and about what this studio refuses to build &lt;a href=&quot;/journal/not-doing-in-2026/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A card deck of encyclopedia articles reverses three of those properties, almost by accident of the form.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The best outcome is that you leave the deck.&lt;/strong&gt; A card exists to make you open the article, and opening the article means you stop swiping and start reading something long. A feed whose best outcome is “user departs into a long article on the Antikythera mechanism” is a bad feed and a good deck.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The ranking input can be a setting.&lt;/strong&gt; In a multilingual reading app the strongest personalisation lever is the language edition, and you choose it in a menu; nothing infers it from dwell time. Interest categories work the same way. A declared preference is worse at maximising engagement than a behavioural model, and better at what a reader wants, which is to be handed something interesting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The deck carries no state to defend.&lt;/strong&gt; Swiping does not level you up, and the deck is no better on day 200 than on day 1. You put it down when you are satisfied, before any supply of bait runs out, which was the whole argument in &lt;a href=&quot;/journal/reading-without-a-feed/&quot;&gt;reading without a feed&lt;/a&gt;. WanderWiki does keep one count outside the deck, the days in a row you have found a new article, shown on its Profile tab, plus an optional daily reminder. Neither changes what the deck shows you.&lt;/p&gt;

&lt;p&gt;A deck is not automatically virtuous. A swipe deck ranked on dwell time with a streak counter bolted on would be a feed in a costume. The form makes the honest version easy to build and the dishonest version obviously unnecessary, and that is all it does.&lt;/p&gt;

&lt;h2 id=&quot;where-wanderwiki-fits-and-where-it-does-not&quot;&gt;Where WanderWiki fits, and where it does not&lt;/h2&gt;

&lt;p&gt;WanderWiki is a discovery client, and that rules some things out.&lt;/p&gt;

&lt;p&gt;It runs on iPhone and iPad, iOS 18.2 and later. It carries 32 Wikipedia language editions out of roughly 340, which is a real limitation. There are four ways in: Random across the full encyclopedia, Browse and For You across 16 interest topics, and Today in History. How random that Random draw really is, and how to make one land on a featured article, is covered in &lt;a href=&quot;/journal/how-to-find-interesting-wikipedia-articles/&quot;&gt;a guide to finding interesting Wikipedia articles&lt;/a&gt;. The app has no ads and no account, and the articles you save stay on the device, in folders. It is free for 20 articles a day; WanderWiki Plus, which adds For You, Today in History and unlimited swiping, is $1.99/month, $8.99/year, or $24.99 once. Paying is what replaces ads and an engagement model.&lt;/p&gt;

&lt;p&gt;The part relevant to this post is the category mapping. In 17 of the 32 editions, interest topics are mapped against that edition’s own category tree, so choosing German plus Science queries Wissenschaft, Physik, and Chemie, and not machine-translated English category names. In the other 15, For You and Browse fall back to random articles from that edition, because English names pointed at a category tree that does not use them would return the wrong articles or none. That is the point from the top of this page applied in one place: the German Wikipedia’s category structure belongs to the German Wikipedia. The data side is documented per app on the &lt;a href=&quot;/transparency/&quot;&gt;transparency page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There are things it does not do. It does not translate: if an article does not exist in the edition you selected, WanderWiki cannot produce it, and that is the correct behaviour. There is no side-by-side view; switching editions switches the deck. And there is no web version.&lt;/p&gt;

&lt;p&gt;Two competitors do some things better. If you want the whole encyclopedia offline, in a place with no connection, &lt;a href=&quot;/alternatives/kiwix/&quot;&gt;Kiwix&lt;/a&gt; is the answer and nothing else is close; downloadable ZIM archives are a different engineering problem from caching the articles you saved. If you want to edit, watch pages, use talk pages, or reach every edition and not just 32, &lt;a href=&quot;/alternatives/wikipedia-app/&quot;&gt;Wikipedia’s own official app&lt;/a&gt; does that and is free. WanderWiki sits in the narrow gap between them, as a way to read the parts of the encyclopedia you were not searching for.&lt;/p&gt;

&lt;h2 id=&quot;tldr&quot;&gt;TL;DR&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Wikipedia language editions are written locally, not translated.&lt;/strong&gt; Each is an independent project with its own editors, notability rules, sourcing norms, and image policy. No English master copy exists for the others to render.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The languages sidebar links concepts.&lt;/strong&gt; Those links live in Wikidata and assert only that two pages are about the same subject. They say nothing about length, framing, or agreement.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Article counts are a bad size ranking.&lt;/strong&gt; English is around 7 million and Cebuano near 6 million, but the second is almost entirely bot-generated stubs. Check the live &lt;a href=&quot;https://meta.wikimedia.org/wiki/List_of_Wikipedias&quot;&gt;List of Wikipedias&lt;/a&gt; before trusting any number on a blog, including this one.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Reading a topic in a second edition is a real research technique.&lt;/strong&gt; Open the edition closest to the subject, let the browser translate, and go through the references list, where local sources usually turn up.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Small editions are thinner, which makes them fragile.&lt;/strong&gt; The published Croatian and Scots cases show what happens when very few people are watching.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;A deck is defensible where a feed is not.&lt;/strong&gt; Its best outcome is you leaving to read something long, its ranking input can be a declared setting, and it has no accumulating state to defend.&lt;/li&gt;
&lt;/ul&gt;
</content>
  </entry>

  <entry>
    <title>Your vet paperwork is a household document, and it should never leave the phone</title>
    <link href="https://lagerland-apps.github.io/journal/vet-paperwork-stays-on-your-phone/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/vet-paperwork-stays-on-your-phone/</id>
    <published>2026-07-12T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Nobody would upload a photo of their driving licence to a free web tool. Plenty of people photograph the dog&apos;s rabies certificate into a cloud pet app without a second thought, and those two documents carry roughly the same household. Here is what is actually printed on vet paperwork, what changes when the image leaves the device, and a four-test checklist you can run on any health app before you trust it with the drawer.</summary>
    <content type="html">&lt;p&gt;Ask someone whether they would upload a photo of their driving licence to a free web tool and they will say no straight away.&lt;/p&gt;

&lt;p&gt;Ask the same person to photograph the dog’s rabies certificate into a pet app and they will not think about it at all. It is the dog’s certificate. The dog does not have a credit rating.&lt;/p&gt;

&lt;p&gt;People file the certificate mentally under the pet, but on paper it is a document about a household with an animal named in it. This post is about that mismatch between how the document feels and what it contains.&lt;/p&gt;

&lt;h2 id=&quot;what-is-actually-printed-on-a-vet-invoice-or-vaccination-certificate&quot;&gt;What is actually printed on a vet invoice or vaccination certificate?&lt;/h2&gt;

&lt;p&gt;Pull one out of the drawer and read it field by field. The exact layout varies by country and practice-management software, but the contents are very consistent.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;What is printed&lt;/th&gt;
      &lt;th&gt;Whose data is it&lt;/th&gt;
      &lt;th&gt;Why it matters if it leaves&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Owner full name&lt;/td&gt;
      &lt;td&gt;Yours&lt;/td&gt;
      &lt;td&gt;The primary identifier on every other field below&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Home address&lt;/td&gt;
      &lt;td&gt;Your household&lt;/td&gt;
      &lt;td&gt;Physical location, tied to a name and a phone number&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Phone number, often email&lt;/td&gt;
      &lt;td&gt;Yours&lt;/td&gt;
      &lt;td&gt;The two fields that make a record joinable to other databases&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Animal name, species, breed, DOB, sex&lt;/td&gt;
      &lt;td&gt;The pet&lt;/td&gt;
      &lt;td&gt;Common security-question and password-reset material&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Microchip transponder code&lt;/td&gt;
      &lt;td&gt;The pet, registered to you&lt;/td&gt;
      &lt;td&gt;A permanent, unique, lifelong identifier for the animal&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Clinic name and address&lt;/td&gt;
      &lt;td&gt;Third party&lt;/td&gt;
      &lt;td&gt;Places you geographically, often within a few kilometres of home&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Treating vet’s name, sometimes licence number&lt;/td&gt;
      &lt;td&gt;Third party&lt;/td&gt;
      &lt;td&gt;Professional identity, not yours to redistribute&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Drug names, dose, route, batch or lot number&lt;/td&gt;
      &lt;td&gt;Clinical&lt;/td&gt;
      &lt;td&gt;Health data about the animal; batch numbers are traceable to supply&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Diagnosis or presenting complaint&lt;/td&gt;
      &lt;td&gt;Clinical&lt;/td&gt;
      &lt;td&gt;The most sensitive line on the page, and often free text&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Invoice number, date, amount, payment method&lt;/td&gt;
      &lt;td&gt;Financial&lt;/td&gt;
      &lt;td&gt;Sometimes a masked card reference or a practice account number&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Two of those deserve a closer look.&lt;/p&gt;

&lt;p&gt;The first is the microchip code, which identifies more than the pet. Transponders sold today generally follow the ISO 11784/11785 standard and carry a 15-digit code, while older chips in the United States may be 9 or 10 digits (&lt;a href=&quot;https://en.wikipedia.org/wiki/Microchip_implant_%28animal%29&quot;&gt;Wikipedia’s summary of animal microchip standards&lt;/a&gt; is a decent overview of the encoding). That code is the key into a registry that holds your name, address and phone. Anyone can type a chip number into the AAHA Universal Pet Microchip Lookup Tool and find out which registry it is enrolled with. The tool returns the registry and not your details, but it is a useful reminder that the number is an index into a database about you. It is more than a serial number on a piece of hardware.&lt;/p&gt;

&lt;p&gt;The second is travel paperwork. The EU pet passport model, described on the European Commission’s &lt;a href=&quot;https://food.ec.europa.eu/animals/movement-pets_en&quot;&gt;pet movement pages&lt;/a&gt;, binds the transponder code to the owner’s name and address in a single booklet, alongside the rabies vaccination record. If you have ever photographed a pet passport, you photographed an identity document with two subjects on it.&lt;/p&gt;

&lt;h2 id=&quot;where-does-the-image-go-on-device-versus-cloud-extraction&quot;&gt;Where does the image go? On-device versus cloud extraction&lt;/h2&gt;

&lt;p&gt;To the user, the feature looks the same either way: you point the camera at a page, a moment passes, and the fields fill in. Underneath are two different architectures, and they differ in the things you cannot see.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Dimension&lt;/th&gt;
      &lt;th&gt;On-device extraction&lt;/th&gt;
      &lt;th&gt;Cloud extraction&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Where the image goes&lt;/td&gt;
      &lt;td&gt;Stays in the app’s container on the phone&lt;/td&gt;
      &lt;td&gt;Uploaded to the operator’s infrastructure, often via a CDN and a queue&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Airplane mode&lt;/td&gt;
      &lt;td&gt;Works. Capture and OCR are OS frameworks&lt;/td&gt;
      &lt;td&gt;Fails, or queues the scan for later upload&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Latency&lt;/td&gt;
      &lt;td&gt;Bounded by the device; no round trip, no rate limit&lt;/td&gt;
      &lt;td&gt;Network round trip plus queue time; degrades on poor connections&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;What a breach exposes&lt;/td&gt;
      &lt;td&gt;Nothing. There is no copy to breach&lt;/td&gt;
      &lt;td&gt;The image, the extracted text, and the account it is attached to&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;What a policy change can do retroactively&lt;/td&gt;
      &lt;td&gt;Nothing. It cannot reach data it never had&lt;/td&gt;
      &lt;td&gt;Re-scope, re-use, or transfer everything already held&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Retention and deletion&lt;/td&gt;
      &lt;td&gt;You delete the record, the file is gone&lt;/td&gt;
      &lt;td&gt;Deletion applies to the live store; backups and logs are a separate question&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Accuracy on hard scans&lt;/td&gt;
      &lt;td&gt;Bounded by what fits on the device&lt;/td&gt;
      &lt;td&gt;Usually better on creased, faded or unusual pages&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Improvement over time&lt;/td&gt;
      &lt;td&gt;Requires an OS or app update&lt;/td&gt;
      &lt;td&gt;Improves server-side with no action from you&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Cost model&lt;/td&gt;
      &lt;td&gt;Compute is free once the device is bought&lt;/td&gt;
      &lt;td&gt;Per-page inference cost, which someone has to fund&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The last row explains much of the rest of the table. Server-side extraction has a marginal cost per page, and that cost has to be recovered through a subscription, a clinic partnership, or the data. Local extraction has no marginal cost at all, which is why a local app can offer scanning without a recurring bill and a cloud app usually cannot.&lt;/p&gt;

&lt;p&gt;Cloud wins two of those rows outright, and anyone selling on-device processing should say so. A hosted model is not constrained by a phone’s memory ceiling or thermal budget, so on a faded thermal printout, a fax of a fax, or a vet’s handwriting in the margin, cloud OCR will frequently read a line a local model misses. It also improves while you sleep: the operator ships a new model and every future scan gets better, with no App Store update and no action from you.&lt;/p&gt;

&lt;h2 id=&quot;which-apple-frameworks-actually-do-the-reading&quot;&gt;Which Apple frameworks actually do the reading?&lt;/h2&gt;

&lt;p&gt;Two frameworks do it, and both ship inside iOS.&lt;/p&gt;

&lt;p&gt;Capture is &lt;a href=&quot;https://developer.apple.com/documentation/visionkit/vndocumentcameraviewcontroller&quot;&gt;VisionKit’s document scanner&lt;/a&gt;, the same camera sheet you have used in Notes and Files. It finds the page edges, corrects perspective so a photo taken at an angle comes out rectangular, handles multi-page documents, and returns clean images.&lt;/p&gt;

&lt;p&gt;Reading is the Vision framework’s &lt;a href=&quot;https://developer.apple.com/documentation/vision/recognizing-text-in-images&quot;&gt;text recognition&lt;/a&gt;, which locates and transcribes text in an image. The set of languages it recognises is enumerable at runtime and has grown across framework revisions, so an app should ask the OS for the list and not hard-code a marketing number.&lt;/p&gt;

&lt;p&gt;Neither framework tells you anything about privacy on its own, and this is where people get caught out. An app can present the VisionKit sheet, get a beautiful deskewed image back, and then POST it straight to a server. The capture UI proves nothing. What matters is what happens to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UIImage&lt;/code&gt; in the next twenty lines of code, and you cannot see those.&lt;/p&gt;

&lt;p&gt;So you test the behaviour instead.&lt;/p&gt;

&lt;h2 id=&quot;how-can-you-tell-whether-an-app-uploads-your-documents&quot;&gt;How can you tell whether an app uploads your documents?&lt;/h2&gt;

&lt;p&gt;There are four tests. None of them requires you to read code, and they work on any health app, pet apps included.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Test&lt;/th&gt;
      &lt;th&gt;How to run it&lt;/th&gt;
      &lt;th&gt;What a clean answer looks like&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Airplane mode&lt;/td&gt;
      &lt;td&gt;Enable airplane mode, then scan a document and try to save it&lt;/td&gt;
      &lt;td&gt;Extraction completes and the record saves, with no spinner and no queue&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Privacy nutrition label&lt;/td&gt;
      &lt;td&gt;On the App Store listing, open App Privacy&lt;/td&gt;
      &lt;td&gt;Nothing under Data Used to Track You; anything collected is Not Linked to You&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Account requirement&lt;/td&gt;
      &lt;td&gt;Try to use the core feature on first launch&lt;/td&gt;
      &lt;td&gt;No sign-up wall. An account implies a server that stores something&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Required Reason API disclosure&lt;/td&gt;
      &lt;td&gt;Check the developer’s stated privacy manifest and SDK list&lt;/td&gt;
      &lt;td&gt;A short list of mundane APIs, and few or no third-party SDKs&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The airplane-mode test is the strongest of the four because it tests behaviour. A marketing page can say “privacy-first” for free, but a scan that completes with the radios off cannot be faked.&lt;/p&gt;

&lt;p&gt;The other three are declarations, and they are worth reading closely. Apple’s &lt;a href=&quot;https://developer.apple.com/app-store/app-privacy-details/&quot;&gt;app privacy details&lt;/a&gt; are self-reported, which is a genuine weakness, but they are a public commitment with consequences if false, and the “Linked to You” versus “Not Linked to You” distinction is the one that matters most. &lt;a href=&quot;https://developer.apple.com/documentation/bundleresources/privacy-manifest-files&quot;&gt;Privacy manifest files&lt;/a&gt; go further: they declare tracking status, tracking domains, and the Required Reason APIs an app calls, each with a category code. A long Required Reason list is not automatically bad, but it is worth reading, and so is the third-party SDK list: an analytics SDK you have never heard of is a data flow you did not choose.&lt;/p&gt;

&lt;p&gt;That is why this studio publishes all of it on a single page. Our &lt;a href=&quot;/transparency/&quot;&gt;transparency page&lt;/a&gt; lists, per app, the declared tracking status, tracking domains, third-party SDKs, network calls and Required Reason API codes. For &lt;a href=&quot;/apps/pawza/&quot;&gt;Pawza&lt;/a&gt; that comes to two Required Reason APIs (app-specific user defaults and file timestamps within the app’s own container), one third-party dependency, an archive library with no network access, and zero tracking domains. Don’t take my word for it: read the page, then run the airplane-mode test yourself.&lt;/p&gt;

&lt;h2 id=&quot;why-the-trade-is-asymmetric&quot;&gt;Why the trade is asymmetric&lt;/h2&gt;

&lt;p&gt;The upload is permanent and the convenience is momentary.&lt;/p&gt;

&lt;p&gt;You save a few seconds by having a server read the page instead of the phone. In exchange, a copy of a document containing your name, your address, your phone number and your pet’s lifelong identifier exists on infrastructure you have never seen, governed by a document you did not negotiate, for a period you cannot verify.&lt;/p&gt;

&lt;p&gt;Everything on the company’s side of that trade can change. Policies get revised. Companies get acquired, and the acquirer inherits the database along with the terms, then revises the terms. Retention windows get longer when storage gets cheaper. A deletion request usually reaches the live database and rarely reaches the backup snapshots, the log lines, or the extracted text already sitting in a derived table.&lt;/p&gt;

&lt;p&gt;On your side, nothing can change, because you cannot un-upload the scan.&lt;/p&gt;

&lt;p&gt;The other half of the asymmetry is who pays for a breach. If a pet-records service is compromised, the company writes a blog post, offers credit monitoring, and continues. You are the one whose home address was in the dump, attached to a phone number, a nearby clinic, and a note about which nights you board the dog. That is exactly the shape of data that makes ordinary fraud and ordinary stalking easier. The same argument applies to any file you casually hand to a web service, which is a point I have made before about &lt;a href=&quot;/journal/your-photos-shouldnt-ride-the-elevator/&quot;&gt;image converters&lt;/a&gt; and about &lt;a href=&quot;/journal/i-will-not-ask-for-your-bank-login/&quot;&gt;apps that ask for your bank login&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The architectural answer is to arrange things so that trust is not required. A scan that never leaves the device is not covered by any future version of anyone’s terms, because there is nothing on the other end to apply them to.&lt;/p&gt;

&lt;h2 id=&quot;what-on-device-processing-actually-costs-you&quot;&gt;What on-device processing actually costs you&lt;/h2&gt;

&lt;p&gt;Our own app has trade-offs too, and a post like this is worthless if it only lists the other side’s compromises.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/apps/pawza/&quot;&gt;Pawza&lt;/a&gt; is built to pass its own airplane-mode test. Capture and extraction both run on the device, there is no Pawza account and no Pawza server to upload to, and you confirm every extracted field before it is written. Records stay on iPhone and iPad with optional sync through your own iCloud.&lt;/p&gt;

&lt;p&gt;The constraints are real. The best extraction needs Pawza Pro and Apple Intelligence, which means iOS 26 or later on a supported device; on older hardware Pawza falls back to OCR-assisted entry, and you confirm more by hand. There is no Android app and no web app, because the entire privacy argument rests on Apple’s on-device frameworks. The free tier also limits how many documents you can scan, which is a business constraint and not a technical one.&lt;/p&gt;

&lt;p&gt;The features we give up are, almost without exception, the ones that need a server. &lt;a href=&quot;/alternatives/vetkeep/&quot;&gt;VetKeep&lt;/a&gt; answers questions about your records in a conversational AI chat, which is far easier to build when the records already sit on a server; if that is the feature you want, the cloud is the honest way to get it today. &lt;a href=&quot;/alternatives/petdesk/&quot;&gt;PetDesk&lt;/a&gt;’s clinic booking and &lt;a href=&quot;/alternatives/11pets/&quot;&gt;11pets&lt;/a&gt;’s Android and web apps are the same story.&lt;/p&gt;

&lt;p&gt;We won’t route the page through a server without telling you and call it scanning. For which documents are worth keeping, what each of them costs, and the full category rundown, the companion post on &lt;a href=&quot;/journal/pet-medical-records-what-to-keep/&quot;&gt;what to keep in a pet medical record&lt;/a&gt; covers the paperwork side.&lt;/p&gt;

&lt;h2 id=&quot;tldr&quot;&gt;TL;DR&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;A vet document is a household document.&lt;/strong&gt; Owner name, home address, phone, email, the animal’s microchip code, the clinic, the treating vet, the drugs and doses, and sometimes a payment reference. The pet is one field among a dozen about you.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The feature looks identical either way.&lt;/strong&gt; You point the camera and the fields fill in. The difference is where the image goes, which you cannot see from the UI.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Airplane mode is the honest test.&lt;/strong&gt; VisionKit capture and Vision text recognition are OS frameworks and need no network. If a scan completes with the radios off, the reading is local.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Cloud extraction wins on hard scans.&lt;/strong&gt; Its bigger models do better on faded and creased pages, and they improve without an app update.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The trade is lopsided.&lt;/strong&gt; The convenience lasts seconds; the copy is permanent, and every term governing it can be rewritten afterwards by someone you never met.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Check four things on any health app:&lt;/strong&gt; airplane mode, the App Store privacy nutrition label, whether an account is forced, and the declared Required Reason APIs and third-party SDKs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The drawer of paper in your kitchen has one useful property no cloud service can match: nobody can query it from another continent.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>Rotating shift schedules explained: DuPont, Pitman, 4-on-4-off, Continental and which are hardest on sleep</title>
    <link href="https://lagerland-apps.github.io/journal/rotating-shift-schedules-explained/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/rotating-shift-schedules-explained/</id>
    <published>2026-07-05T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">DuPont, Pitman, Panama, 4-on-4-off, Continental, Southern swing: most rotating rosters are one of a handful of named patterns, and the names get used loosely. This is a reference for what each one actually is, how it moves you between days and nights, and what the research says about which rotations cost the most sleep.</summary>
    <content type="html">&lt;p&gt;A rotating schedule is a roster in which your shift times change on a repeating cycle, usually so that a fixed number of crews can cover a workplace around the clock. A handful of named patterns cover most of them. The names are used loosely, and two employers can mean different rosters by the same word, so the sequence matters more than the label.&lt;/p&gt;

&lt;h2 id=&quot;what-are-the-common-rotating-shift-schedules&quot;&gt;What are the common rotating shift schedules?&lt;/h2&gt;

&lt;p&gt;D is a day shift, E an evening (afternoon or swing) shift, N a night shift. Average hours assume no overtime.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Pattern&lt;/th&gt;
      &lt;th&gt;Shift length&lt;/th&gt;
      &lt;th&gt;Sequence&lt;/th&gt;
      &lt;th&gt;Cycle&lt;/th&gt;
      &lt;th&gt;Average hours a week&lt;/th&gt;
      &lt;th&gt;Moving between days and nights&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;DuPont&lt;/td&gt;
      &lt;td&gt;12 h&lt;/td&gt;
      &lt;td&gt;4N, 3 off, 3D, 1 off, 3N, 3 off, 4D, 7 off&lt;/td&gt;
      &lt;td&gt;28 days&lt;/td&gt;
      &lt;td&gt;42&lt;/td&gt;
      &lt;td&gt;Four switches per cycle&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Pitman / Panama (2-2-3)&lt;/td&gt;
      &lt;td&gt;12 h&lt;/td&gt;
      &lt;td&gt;2 on, 2 off, 3 on, 2 off, 2 on, 3 off&lt;/td&gt;
      &lt;td&gt;14 days&lt;/td&gt;
      &lt;td&gt;42&lt;/td&gt;
      &lt;td&gt;Fixed days or nights, or a swap every 2 or 4 weeks&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;4-on-4-off&lt;/td&gt;
      &lt;td&gt;12 h&lt;/td&gt;
      &lt;td&gt;4 on, 4 off; rotating version 4D, 4 off, 4N, 4 off&lt;/td&gt;
      &lt;td&gt;8 or 16 days&lt;/td&gt;
      &lt;td&gt;42&lt;/td&gt;
      &lt;td&gt;Four days off before every switch&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Continental&lt;/td&gt;
      &lt;td&gt;8 h&lt;/td&gt;
      &lt;td&gt;Runs of 2 or 3 mornings, afternoons and nights, then days off&lt;/td&gt;
      &lt;td&gt;28 days&lt;/td&gt;
      &lt;td&gt;42&lt;/td&gt;
      &lt;td&gt;Forward, every 2 to 3 days&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Southern swing&lt;/td&gt;
      &lt;td&gt;8 h&lt;/td&gt;
      &lt;td&gt;7D, 2 off, 7E, 2 off, 7N, 3 off&lt;/td&gt;
      &lt;td&gt;28 days&lt;/td&gt;
      &lt;td&gt;42&lt;/td&gt;
      &lt;td&gt;Forward, weekly&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2-2-2 fast forward&lt;/td&gt;
      &lt;td&gt;8 h&lt;/td&gt;
      &lt;td&gt;2D, 2E, 2N, 2 off&lt;/td&gt;
      &lt;td&gt;8 days&lt;/td&gt;
      &lt;td&gt;42&lt;/td&gt;
      &lt;td&gt;Forward, every 2 days&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Fixed five and two&lt;/td&gt;
      &lt;td&gt;8 h&lt;/td&gt;
      &lt;td&gt;5 on, 2 off, always the same shift&lt;/td&gt;
      &lt;td&gt;7 days&lt;/td&gt;
      &lt;td&gt;40&lt;/td&gt;
      &lt;td&gt;None&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Why does almost every row say 42? A week has 168 hours. Four crews covering it in turn work 168 ÷ 4 = 42 hours each on average, whatever the shift length. What differs is how the hours bunch up. Start DuPont on a Monday and its four weeks come out at 48, 72, 48 and 0 hours. Start Pitman on a Monday and it alternates a five-shift week that includes the weekend with a two-shift week that leaves Friday to Sunday free, which is where its every-other-weekend-off reputation comes from.&lt;/p&gt;

&lt;h2 id=&quot;why-do-pitman-panama-and-2-2-3-sound-like-the-same-thing&quot;&gt;Why do Pitman, Panama and 2-2-3 sound like the same thing?&lt;/h2&gt;

&lt;p&gt;They mostly are. Scheduling guides use all three names for the same 14-day, 12-hour cadence, and some keep Panama for the version where crews also alternate between days and nights. Continental is looser still: in some workplaces it means the 8-hour, 28-day forward rotation in the table, in others any 2-2-3 rota. Whatever your roster is called, write out the next 28 days as D, E, N and off, since that sequence is what your sleep responds to.&lt;/p&gt;

&lt;h2 id=&quot;how-does-each-pattern-move-between-days-and-nights&quot;&gt;How does each pattern move between days and nights?&lt;/h2&gt;

&lt;p&gt;How hard a switch is depends on which way the clock moves and on how many hours you get between the last shift of one kind and the first of the next.&lt;/p&gt;

&lt;p&gt;NIOSH’s free training course for nurses names the direction (&lt;a href=&quot;https://www.cdc.gov/niosh/work-hour-training-for-nurses/longhours/mod5/04.html&quot;&gt;Module 5&lt;/a&gt;). Day to evening to night is a forward rotation; night to evening to day is a backward one. It also names the speed: fast rotation changes shift within a week, slow rotation keeps each shift for two weeks or more, and weekly rotation sits in between.&lt;/p&gt;

&lt;p&gt;In an 8-hour, three-shift system the gaps get small quickly. Move forward from a 14:00 to 22:00 afternoon to a 22:00 to 06:00 night the next day and you have 24 hours between shifts. Move backward from that night to an afternoon shift the same day and you have 8. A 22:00 finish followed by a 06:00 start also leaves 8 hours, and those 8 hours have to cover the commute, a meal and sleep.&lt;/p&gt;

&lt;p&gt;Twelve-hour systems have only days and nights, so the gap matters more than the direction. Applied to the table:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;DuPont’s tightest point is the middle of the cycle: three day shifts, one day off, three nights. The other switch, nights to days, comes after three days off.&lt;/li&gt;
  &lt;li&gt;A rotating 4-on-4-off always puts four days off between a block of days and a block of nights.&lt;/li&gt;
  &lt;li&gt;Pitman crews on fixed days or fixed nights never switch. Rotating Pitman crews switch every two or four weeks, which is a slow rotation.&lt;/li&gt;
  &lt;li&gt;Continental and 2-2-2 rosters change every two or three days, always forward.&lt;/li&gt;
  &lt;li&gt;Southern swing rotates forward but weekly, with seven nights in a row.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;why-is-backward-rotation-harder-on-sleep&quot;&gt;Why is backward rotation harder on sleep?&lt;/h2&gt;

&lt;p&gt;The usual explanation is that the human body clock runs slightly longer than 24 hours, so it is easier to push it later, as a forward rotation does, than to pull it earlier, as a backward one does.&lt;/p&gt;

&lt;p&gt;The largest study I found on rotation direction and sleep is &lt;a href=&quot;https://pmc.ncbi.nlm.nih.gov/articles/PMC5011337/&quot;&gt;Shon and colleagues’ 2016 study of 4,750 Korean electronics workers&lt;/a&gt; on a three-shift system with 06:00, 14:00 and 22:00 starts. About 38% of the backward-rotating workers had poor sleep quality on the Pittsburgh Sleep Quality Index, against about 28% of the forward-rotating ones. After adjustment, backward rotation carried 1.95 times the odds of poor sleep, and the link was stronger in workers aged 30 and over. It was a cross-sectional study and didn’t record rotation speed, so it shows an association, not proof.&lt;/p&gt;

&lt;p&gt;Studies that changed people’s schedules point the same way. A review of field research by &lt;a href=&quot;https://www.sjweh.fi/article/2900&quot;&gt;Sallinen and Kecklund (2010)&lt;/a&gt; found that moving workers from slowly backward-rotating to rapidly forward-rotating shifts improved alertness and, to some extent, sleep. NIOSH’s guidance says forward rotations are easier to adjust to, and that weekly rotation is the hardest speed and best avoided (&lt;a href=&quot;https://www.cdc.gov/niosh/work-hour-training-for-nurses/longhours/mod5/06.html&quot;&gt;Module 5, continued&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;What the evidence doesn’t settle is fast versus slow. NIOSH notes that some U.S. researchers favour slow rotations of two weeks or more, which give the body clock time to adjust, while some European researchers favour fast forward rotations, which mean fewer nights in a row. Its conclusion is that it isn’t clear which is best for healthcare workers.&lt;/p&gt;

&lt;h2 id=&quot;why-do-quick-returns-matter-so-much&quot;&gt;Why do quick returns matter so much?&lt;/h2&gt;

&lt;p&gt;A quick return is a changeover with 11 hours or less between two shifts. &lt;a href=&quot;https://cronfa.swansea.ac.uk/Record/cronfa22100&quot;&gt;Vedaa and colleagues’ 2016 systematic review&lt;/a&gt; of 22 studies found signs that quick returns harm sleep, sleepiness and fatigue in the short term; the evidence on longer-term health and work-life balance was inconclusive. Sallinen and Kecklund saw the same pattern across shift systems: night shifts, early-morning shifts and quick returns went with shorter sleep and more sleepiness.&lt;/p&gt;

&lt;p&gt;The eleven-hour line comes from regulation and guidance. It is the minimum daily rest in the &lt;a href=&quot;https://eur-lex.europa.eu/eli/dir/2003/88/oj&quot;&gt;EU Working Time Directive&lt;/a&gt;, which allows exceptions when shift workers change shift, and the minimum gap between shifts that NIOSH’s course cites from Knauth and Hornberger. The course’s own example is an evening shift ending at 11:30 p.m. followed by a 7 or 8 a.m. day shift. Take out the drive both ways, a meal and the time it takes to fall asleep, and even a full 11 hours leaves well short of a full night.&lt;/p&gt;

&lt;h2 id=&quot;which-schedules-are-hardest-on-sleep&quot;&gt;Which schedules are hardest on sleep?&lt;/h2&gt;

&lt;p&gt;No schedule is best for everyone. NIOSH says researchers &lt;a href=&quot;https://www.cdc.gov/niosh/work-hour-training-for-nurses/longhours/mod5/04.html&quot;&gt;cannot recommend a single best design&lt;/a&gt;. Its scheduling guidelines (&lt;a href=&quot;https://www.cdc.gov/niosh/work-hour-training-for-nurses/longhours/mod5/05.html&quot;&gt;part 1&lt;/a&gt;, &lt;a href=&quot;https://www.cdc.gov/niosh/work-hour-training-for-nurses/longhours/mod5/06.html&quot;&gt;part 2&lt;/a&gt;) and the reviews above still make a fair checklist to hold a roster against:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Feature&lt;/th&gt;
      &lt;th&gt;What the guidance says&lt;/th&gt;
      &lt;th&gt;Where it turns up&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Backward steps&lt;/td&gt;
      &lt;td&gt;Forward rotation is easier to adjust to&lt;/td&gt;
      &lt;td&gt;Any roster with a late finish followed by an early start&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Quick returns&lt;/td&gt;
      &lt;td&gt;At least 11 hours between shifts&lt;/td&gt;
      &lt;td&gt;Backward steps in 8-hour systems, overtime added to a late shift&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Weekly rotation&lt;/td&gt;
      &lt;td&gt;The hardest speed, best avoided&lt;/td&gt;
      &lt;td&gt;Southern swing&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Long runs of nights&lt;/td&gt;
      &lt;td&gt;Keep consecutive nights to a minimum on rotating schedules&lt;/td&gt;
      &lt;td&gt;Southern swing (7), DuPont and rotating 4-on-4-off (4)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Early starts&lt;/td&gt;
      &lt;td&gt;6 a.m. or earlier tends to shorten sleep&lt;/td&gt;
      &lt;td&gt;06:00 mornings in Continental and other 8-hour rotations&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Long night shifts&lt;/td&gt;
      &lt;td&gt;8 hours or less is better tolerated on evenings and nights&lt;/td&gt;
      &lt;td&gt;12-hour nights in DuPont, Pitman and 4-on-4-off&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Rest after a run&lt;/td&gt;
      &lt;td&gt;Consider two rest days after three 12-hour shifts&lt;/td&gt;
      &lt;td&gt;DuPont’s three days, one day off, three nights&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;On twelve-hour shifts, Sallinen and Kecklund found that moving from 8- to 12-hour shifts did not necessarily harm sleep. Longer shifts mean fewer changeovers and so fewer chances for a quick return, which is part of why 12-hour rosters have spread despite the long nights.&lt;/p&gt;

&lt;h2 id=&quot;what-can-you-do-on-a-roster-you-didnt-choose&quot;&gt;What can you do on a roster you didn’t choose?&lt;/h2&gt;

&lt;p&gt;Most people can’t redesign their schedule, but they can find its weak points. Write out a full cycle and mark every gap under 11 hours and every switch onto nights. Those are the days to protect: a nap before the first night (the &lt;a href=&quot;/journal/how-to-sleep-after-a-night-shift/&quot;&gt;night-shift sleep guide&lt;/a&gt; covers how long and when), nothing extra planned on the changeover day, and an honest look at whether you are fit to drive after the last night.&lt;/p&gt;

&lt;p&gt;NIOSH also says nurses adjust better when they have some control over their schedules. If your workplace allows swaps, the backward steps and quick returns are the shifts to trade away first. If you still can’t sleep after several weeks on a rotation, the American Academy of Sleep Medicine’s page on &lt;a href=&quot;https://sleepeducation.org/sleep-disorders/shift-work/&quot;&gt;shift work disorder&lt;/a&gt; describes when that becomes a conversation with a doctor.&lt;/p&gt;

&lt;h2 id=&quot;where-aftershift-fits&quot;&gt;Where AfterShift fits&lt;/h2&gt;

&lt;p&gt;I built &lt;a href=&quot;/apps/aftershift/&quot;&gt;AfterShift&lt;/a&gt; for people on these rosters, and it doesn’t need to know what your pattern is called. It reads shifts from your calendar, working out from the title and start time whether each is a day, evening, night or on-call shift, or you add them by hand. Then it measures each window from the end of one shift to the start of the next, not a midnight-to-midnight day.&lt;/p&gt;

&lt;p&gt;Two parts of it are written for the switches above. When your next shift starts earlier on the clock than the last one, a backward step, the plan calls the gap an available sleep window, notes that fast shift changes often shorten continuous sleep, and suggests a nap. When the whole gap is shorter than your sleep target, the Shift Recovery Score is capped at 79, the top of Good, because a full sleep was never possible in that window; days off are exempt. The &lt;a href=&quot;/apps/aftershift/methodology/&quot;&gt;methodology page&lt;/a&gt; has the weights and caps, and a sleep-debt trend shows which stretches of a cycle left you furthest behind.&lt;/p&gt;

&lt;p&gt;The app can’t change your roster, but it gives you a record of which changeovers cost you the most sleep, which is useful evidence if you ever ask to swap them. The &lt;a href=&quot;/journal/building-a-sleep-app-for-night-shifts/&quot;&gt;design post&lt;/a&gt; explains why the app measures shift to shift in the first place.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>Find every recurring charge you are paying, without linking a bank account</title>
    <link href="https://lagerland-apps.github.io/journal/find-every-recurring-charge/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/find-every-recurring-charge/</id>
    <published>2026-07-01T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Most people audit their subscriptions by scrolling a bank statement, which almost always misses the expensive ones. Recurring charges are spread across eight lists, and the yearly ones are invisible eleven months out of twelve. This is the full checklist, in the order that finds the most money first.</summary>
    <content type="html">&lt;p&gt;The standard advice for finding your subscriptions is to look at your bank statement, which is the worst place to start.&lt;/p&gt;

&lt;p&gt;A statement is a record of what already charged inside the window you happen to be looking at. Open three months of it and you will see every monthly subscription you have, which are the ones you already remember, and roughly a quarter of your yearly ones, which are the ones you don’t. The charges that hurt renew long after the decision that created them, and a short statement scan cannot show them to you.&lt;/p&gt;

&lt;p&gt;There is no single list. Your recurring charges are scattered across four billing systems and four records only you can search, none of which talk to each other, and each already has a screen showing its own slice. The audit is a route through those screens in a sensible order, and the statement comes last.&lt;/p&gt;

&lt;h2 id=&quot;the-audit-checklist-in-order-of-what-it-finds&quot;&gt;The audit checklist, in order of what it finds&lt;/h2&gt;

&lt;p&gt;Run these top to bottom. The first four are billing screens you already own, and together they take about five minutes once you know where they live. The last four are the sweep.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;#&lt;/th&gt;
      &lt;th&gt;Where&lt;/th&gt;
      &lt;th&gt;How to get there&lt;/th&gt;
      &lt;th&gt;What it catches&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;Apple subscriptions&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Settings, tap your name at the top, then Subscriptions (on Mac: App Store, click your name, Account Settings)&lt;/td&gt;
      &lt;td&gt;Everything billed through the App Store, active and recently expired, with next renewal date and price&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;Google Play subscriptions&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Play Store app, tap your profile icon, Payments and subscriptions, Subscriptions&lt;/td&gt;
      &lt;td&gt;Android-side app subscriptions, plus anything you first bought on an Android device years ago&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;PayPal automatic payments&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;paypal.com, Settings, Payments, then the automatic payments or recurring payments list&lt;/td&gt;
      &lt;td&gt;Merchant billing agreements set up outside the app stores: hosting, newsletters, older SaaS, donations&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;Amazon memberships&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Amazon Account, Memberships and Subscriptions; then separately Subscribe and Save&lt;/td&gt;
      &lt;td&gt;Prime, Audible, Kindle Unlimited, channel add-ons, and every household item on a recurring shipment&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;5&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;Email receipts&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Search your inbox for &lt;em&gt;receipt&lt;/em&gt;, &lt;em&gt;your subscription&lt;/em&gt;, &lt;em&gt;renews on&lt;/em&gt;, &lt;em&gt;invoice&lt;/em&gt;, &lt;em&gt;auto-renew&lt;/em&gt;&lt;/td&gt;
      &lt;td&gt;Direct-to-merchant subscriptions that appear in none of the screens above&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;6&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;Purchase history&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Apple’s purchase history page (a separate record from the Subscriptions screen)&lt;/td&gt;
      &lt;td&gt;One-off purchases and lapsed subscriptions, useful for reconstructing what you once signed up for&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;7&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;13 months of card statements&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Your card issuer’s site; export CSV if offered and sort by merchant&lt;/td&gt;
      &lt;td&gt;Everything the first six missed, including annual renewals (see the arithmetic below)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;8&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;Password manager&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;The saved-logins list in your browser, iCloud Keychain, or 1Password&lt;/td&gt;
      &lt;td&gt;An inventory of accounts you forgot you created, each of which may or may not be billing you&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Some notes on the paths, which change over time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Apple.&lt;/strong&gt; For most iPhone users this one screen finds the most, and people skip it because they assume it lists only apps. It lists anything billed through your Apple Account, including subscriptions bought inside apps that are themselves free. Apple documents the screen and the cancel flow in &lt;a href=&quot;https://support.apple.com/en-us/118428&quot;&gt;If you want to cancel a subscription from Apple&lt;/a&gt;. The entry point has moved across iOS versions, so if the path above does not match your device, search Settings for the word &lt;em&gt;subscriptions&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Google Play.&lt;/strong&gt; Even if you have not owned an Android phone in years, check it. Play subscriptions started before you switched keep billing the card on file. Google’s own instructions are on the &lt;a href=&quot;https://support.google.com/googleplay/answer/7018481&quot;&gt;Play Help page for cancelling or changing a subscription&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PayPal.&lt;/strong&gt; Almost everyone skips this step, and the strangest charges live here, because PayPal billing agreements were a common way for small merchants to take recurring payments long before the app stores existed. PayPal calls them automatic payments and explains the list in &lt;a href=&quot;https://www.paypal.com/us/cshelp/article/what-is-an-automatic-payment-and-how-do-i-update-or-cancel-one-pcc140&quot;&gt;What is an automatic payment and how do I update or cancel one&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amazon.&lt;/strong&gt; There are two separate lists, and the second is easy to miss. &lt;a href=&quot;https://www.amazon.com/yourmembershipsandsubscriptions&quot;&gt;Memberships and Subscriptions&lt;/a&gt; covers Prime and the digital add-ons. Subscribe and Save is a different screen entirely, reached from the same account page, and it is full of things you set to repeat every two months in 2023 and have been receiving ever since.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Email and purchase history.&lt;/strong&gt; Search your inbox for renewal language, not brand names, because you are looking for the merchants you cannot name. If your mail client supports it, restrict the search to messages containing the word &lt;em&gt;renew&lt;/em&gt; and a currency symbol. Then read Apple’s own record, which is separate from the Subscriptions screen and reaches further back: &lt;a href=&quot;https://support.apple.com/en-us/118212&quot;&gt;View your purchase history for the App Store and other Apple media services&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Statements.&lt;/strong&gt; Read 13 months, not three, for the reason in the next section.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Password manager.&lt;/strong&gt; It is not a billing record, so do it last, but it is a good memory aid. Sort your saved logins by date created and read the oldest hundred. Some of those accounts are still charging you, and a name you had genuinely forgotten is often the fastest route to the receipt.&lt;/p&gt;

&lt;h2 id=&quot;which-recurring-charges-hide-best&quot;&gt;Which recurring charges hide best?&lt;/h2&gt;

&lt;p&gt;Some charges are harder to find than others. These categories survive a casual audit, ranked roughly by how often I have seen them survive one.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;What hides&lt;/th&gt;
      &lt;th&gt;Why the usual audit misses it&lt;/th&gt;
      &lt;th&gt;Where it actually shows up&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Annual renewals&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Bought 11 months ago, invisible on a 90-day statement scan, no monthly reminder&lt;/td&gt;
      &lt;td&gt;Platform subscription screens, or a 13-month statement sweep&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Converted free trials&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;The signup and the first charge are separated by 7 to 30 days, so the charge arrives with no decision attached to it&lt;/td&gt;
      &lt;td&gt;Apple or Play subscriptions screen; email receipt for the first real charge&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;In-app subscriptions inside a free app&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;The app icon says free, so nobody thinks to check it&lt;/td&gt;
      &lt;td&gt;Apple or Play subscriptions screen, which exists for exactly this&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Per-seat tools bought for one project&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Billed to whoever set it up, often at 2 to 5 seats, long after the project ended&lt;/td&gt;
      &lt;td&gt;Email receipts, PayPal, or the tool’s own billing page&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Family plans someone else administers&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;The charge is not on your card at all, so it is invisible to every method in this post&lt;/td&gt;
      &lt;td&gt;Ask. There is no technical route to this one&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Domain and hosting renewals&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Usually annual or biennial, and registrars renew silently by design&lt;/td&gt;
      &lt;td&gt;Registrar billing page, PayPal automatic payments, email&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Insurance and memberships renewing by post&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Never touched a card or an app store; renewal notice arrives on paper&lt;/td&gt;
      &lt;td&gt;Direct debit list at your bank, and the paper itself&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The last row is where any app-based audit stops working. A direct debit set up by post is not in Apple’s records, PayPal’s or your inbox, and on the statement it looks like an ordinary bank transfer, not a card charge. The only reliable route is your bank’s own standing order and direct debit list, which you can read without granting anyone else access to it.&lt;/p&gt;

&lt;h2 id=&quot;why-does-a-yearly-charge-survive-audits-a-monthly-one-cannot&quot;&gt;Why does a yearly charge survive audits a monthly one cannot?&lt;/h2&gt;

&lt;p&gt;Because you see it one-twelfth as often. The numbers are worth spelling out, because intuition says the opposite: people assume the big annual charge is the memorable one.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Billing cycle&lt;/th&gt;
      &lt;th&gt;Charges per year&lt;/th&gt;
      &lt;th&gt;Chance it appears in a 30-day scan&lt;/th&gt;
      &lt;th&gt;In a 90-day scan&lt;/th&gt;
      &lt;th&gt;In a 13-month scan&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Monthly&lt;/td&gt;
      &lt;td&gt;12&lt;/td&gt;
      &lt;td&gt;~100%&lt;/td&gt;
      &lt;td&gt;100%&lt;/td&gt;
      &lt;td&gt;100%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Quarterly&lt;/td&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;~33%&lt;/td&gt;
      &lt;td&gt;~100%&lt;/td&gt;
      &lt;td&gt;100%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Every 6 months&lt;/td&gt;
      &lt;td&gt;2&lt;/td&gt;
      &lt;td&gt;~16%&lt;/td&gt;
      &lt;td&gt;~50%&lt;/td&gt;
      &lt;td&gt;100%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Annual&lt;/td&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;~8%&lt;/td&gt;
      &lt;td&gt;~25%&lt;/td&gt;
      &lt;td&gt;100%&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The percentages are just the window divided by the cycle length: a 90-day window is 90/365 of a year, so it contains an annual charge about a quarter of the time. We audit in three-month windows out of habit, and three months is the wrong window for a twelve-month event.&lt;/p&gt;

&lt;p&gt;Add cost to that. A $99-per-year subscription and a $8.25-per-month subscription cost you the same amount over a year. You meet one of them twelve times. You meet the other once, in a month you were not looking, in an amount large enough that you assume it was something else. The yearly plan is usually the better deal and always the harder one to keep track of, which is also why companies push the annual discount so hard.&lt;/p&gt;

&lt;p&gt;So scan 13 months, not 12, so a renewal sitting on the boundary cannot slip through. And when you find an annual charge, write the renewal date down on the spot: you will not see it again for a year, and the audit that found it will not run again in time.&lt;/p&gt;

&lt;h2 id=&quot;what-does-a-bank-linked-app-catch-that-a-checklist-does-not&quot;&gt;What does a bank-linked app catch that a checklist does not?&lt;/h2&gt;

&lt;p&gt;Three specific things, and they are worth naming.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Charges you never knew existed.&lt;/strong&gt; A checklist can only find things that appear in a record you thought to open. A transaction feed finds the charge that arrives under a merchant descriptor you cannot decode, such as a payment processor’s name, a parent company or an eight-character string. No amount of manual discipline reproduces that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Price rises.&lt;/strong&gt; You entered $9.99 for a service in 2024 and it is $13.99 now. A manual list keeps telling you $9.99 until you notice. Software reading the actual charge sees the new number the month it changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Duplicates.&lt;/strong&gt; Two accounts for one service because you signed up on two devices, a charge that continued after a cancellation that did not take, a trial you converted twice. A list built from memory repeats these errors, because memory is where they came from.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/alternatives/rocket-money/&quot;&gt;Rocket Money&lt;/a&gt; does all three, and does them well. If your problem is &lt;em&gt;I do not know what I am paying for&lt;/em&gt;, an aggregator-connected tool is the right choice. The cost is the one I wrote about at length in &lt;a href=&quot;/journal/i-will-not-ask-for-your-bank-login/&quot;&gt;I will not ask for your bank login&lt;/a&gt;: connecting a bank grants an aggregator persistent read access to every transaction in the account, including the ones that are not recurring, and that access continues until you revoke it. You get automatic discovery; the aggregator gets your grocery shopping, your medical copays, and your salary.&lt;/p&gt;

&lt;p&gt;The checklist above answers &lt;em&gt;how do I get the discovery without the access&lt;/em&gt;. It is slower, an afternoon of work against one tap. It also ends: once you have the list, you have it, and upkeep is a few minutes a quarter.&lt;/p&gt;

&lt;h2 id=&quot;what-do-you-do-with-the-list-once-you-have-it&quot;&gt;What do you do with the list once you have it?&lt;/h2&gt;

&lt;p&gt;Most audits fail at this step. People find eleven forgotten charges, cancel four, feel good, and then rebuild the same mess over eighteen months, because nothing captured the seven they kept or the renewal dates attached to them. Once you know what you are keeping, &lt;a href=&quot;/journal/how-to-organize-bills-each-month/&quot;&gt;a bill calendar built around your paydays&lt;/a&gt; shows which paycheck has to cover each charge.&lt;/p&gt;

&lt;p&gt;The list needs to live somewhere that projects forward. A note does not, and a spreadsheet does until about the third week. &lt;a href=&quot;/apps/allpaid/&quot;&gt;AllPaid&lt;/a&gt; is the studio’s app for this job: you type a service name, it auto-fills the typical price, billing cycle and category from a built-in catalogue of 40 common services (Netflix, Spotify, ChatGPT, Claude, Adobe, Microsoft 365, iCloud, rent, utilities), and from then on every bill is projected onto a monthly calendar with one reminder before each due date. It is free, with Pro at $1.99/month, $12.99/year, or $24.99 once, and it never asks for a bank login because it has no mechanism to use one. Bills stay in local storage on the iPhone; the &lt;a href=&quot;/transparency/&quot;&gt;transparency page&lt;/a&gt; lists third-party SDKs (none) and the empty tracking-domain list.&lt;/p&gt;

&lt;p&gt;That limitation is the reason this post exists. AllPaid cannot find a charge you never typed in, and it will not notice a price rise until you edit the amount yourself. It holds the list; the checklist above is how you build it.&lt;/p&gt;

&lt;p&gt;If what you want is a subscriptions-only tracker with a lighter footprint, &lt;a href=&quot;/alternatives/bobby/&quot;&gt;Bobby&lt;/a&gt; and &lt;a href=&quot;/alternatives/subby/&quot;&gt;Subby&lt;/a&gt; are both good and both on-device. Bobby unlocks unlimited subscriptions for a small one-time purchase and Subby is freemium with its own premium unlock, but neither covers rent, utilities and one-off bills alongside the subscriptions. If you want the same list readable from a laptop and a phone and a work machine, &lt;a href=&quot;/alternatives/trackmysubs/&quot;&gt;TrackMySubs&lt;/a&gt; is browser-based and syncs across everything, though it is a web account, not a local file. The broader category comparison lives in &lt;a href=&quot;/guides/bill-tracker-without-bank-connection/&quot;&gt;the guide to bill tracking without a bank connection&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;when-to-re-run-it&quot;&gt;When to re-run it&lt;/h2&gt;

&lt;p&gt;Quarterly for the four platform screens, which is five minutes once the paths are muscle memory. Annually for the 13-month statement sweep and the password-manager read, in the same calendar month each year so consecutive sweeps overlap and leave no gap.&lt;/p&gt;

&lt;p&gt;The most useful habit is to write down the conversion date the moment you start a free trial. Converted trials are the one category on the hiding list you can remove at signup, a year before you would otherwise go looking.&lt;/p&gt;

&lt;h2 id=&quot;tldr&quot;&gt;TL;DR&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;There is no one list. Recurring charges live in Apple subscriptions, Google Play, PayPal automatic payments, Amazon memberships and Subscribe and Save, your email receipts, and your card statement. Check them in that order.&lt;/li&gt;
  &lt;li&gt;Start with Apple, not the bank statement. Settings, tap your name, Subscriptions: it covers everything billed through the App Store, including subscriptions inside apps that are themselves free.&lt;/li&gt;
  &lt;li&gt;Scan 13 months of statements, not three. A 90-day window contains an annual renewal only about a quarter of the time, which is why yearly charges survive audits that monthly ones cannot.&lt;/li&gt;
  &lt;li&gt;PayPal and Subscribe and Save are the two most-skipped steps. Years of small-merchant billing agreements live in the first; recurring household shipments live in the second.&lt;/li&gt;
  &lt;li&gt;A bank-linked app does better on three things: charges you never knew existed, price rises, and duplicates. The price is aggregator read access to every transaction, forever, including the ones that are not recurring.&lt;/li&gt;
  &lt;li&gt;The checklist finds the charges. Something that projects renewal dates forward keeps them from coming back.&lt;/li&gt;
&lt;/ul&gt;
</content>
  </entry>

  <entry>
    <title>How to calculate MRR for App Store subscriptions from Apple&apos;s Subscription report</title>
    <link href="https://lagerland-apps.github.io/journal/how-to-calculate-mrr-for-app-store-subscriptions/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/how-to-calculate-mrr-for-app-store-subscriptions/</id>
    <published>2026-06-27T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">App Store Connect&apos;s Analytics dashboard now shows an MRR figure, but Apple doesn&apos;t publish how it gets there. The daily Subscription report has every input you need to work it out yourself. The arithmetic is one line. When two dashboards disagree, the cause is almost always one of four decisions around that line.</summary>
    <content type="html">&lt;p&gt;Monthly recurring revenue, for an app that sells subscriptions through the App Store, is what your active paid subscriptions earn you per month once every plan is put on a monthly footing. App Store Connect’s daily &lt;a href=&quot;https://developer.apple.com/help/app-store-connect/reference/reporting/subscription-report&quot;&gt;Subscription report&lt;/a&gt; holds every input. For each row:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MRR = Developer Proceeds × Active Standard Price Subscriptions ÷ plan length in months&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add the rows, converting currencies before you add across them, and that is the day’s MRR. The rest of this page is about which columns go into that line, and why.&lt;/p&gt;

&lt;h2 id=&quot;which-columns-in-the-subscription-report-matter&quot;&gt;Which columns in the Subscription report matter?&lt;/h2&gt;

&lt;p&gt;The report comes in a daily version only, and you can download it from Sales and Trends or through the App Store Connect API’s &lt;a href=&quot;https://developer.apple.com/documentation/appstoreconnectapi/get-v1-salesreports&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;salesReports&lt;/code&gt;&lt;/a&gt; endpoint. One subscription usually fills several rows, broken out by columns such as country, price and proceeds rate. These are the columns that decide MRR, paraphrasing Apple’s definitions:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Column&lt;/th&gt;
      &lt;th&gt;What it holds&lt;/th&gt;
      &lt;th&gt;Role in MRR&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Standard Subscription Duration&lt;/td&gt;
      &lt;td&gt;The plan length: 7 Days, 1 Month, 2 Months, 3 Months, 6 Months or 1 Year&lt;/td&gt;
      &lt;td&gt;The divisor&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Developer Proceeds&lt;/td&gt;
      &lt;td&gt;What you earn per subscription on that row&lt;/td&gt;
      &lt;td&gt;The amount per subscriber&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Proceeds Currency&lt;/td&gt;
      &lt;td&gt;The currency those proceeds are earned in&lt;/td&gt;
      &lt;td&gt;Add per currency before converting&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Proceeds Reason&lt;/td&gt;
      &lt;td&gt;Rate After One Year when a renewal earns 85% of the price instead of 70%&lt;/td&gt;
      &lt;td&gt;Nothing to do: the proceeds already reflect it&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Active Standard Price Subscriptions&lt;/td&gt;
      &lt;td&gt;Paid subscriptions currently active, without free trials, subscription offers, introductory offers or marketing opt-ins&lt;/td&gt;
      &lt;td&gt;The multiplier&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Active Free Trial Introductory Offer Subscriptions&lt;/td&gt;
      &lt;td&gt;Introductory offers currently in a free trial&lt;/td&gt;
      &lt;td&gt;Left out: a trial earns nothing yet&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Active Pay Up Front and Pay as You Go Introductory Offer Subscriptions&lt;/td&gt;
      &lt;td&gt;Introductory offers at a reduced price&lt;/td&gt;
      &lt;td&gt;Left out of a standard-price MRR&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Billing Retry, Grace Period&lt;/td&gt;
      &lt;td&gt;Subscriptions with a billing problem Apple is still trying to fix&lt;/td&gt;
      &lt;td&gt;Left out&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Subscribers&lt;/td&gt;
      &lt;td&gt;People with access, including family members, filled in only when a row covers more than 3 subscriptions&lt;/td&gt;
      &lt;td&gt;Not a multiplier: it counts people, not paid subscriptions&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;how-do-you-turn-each-plan-length-into-months&quot;&gt;How do you turn each plan length into months?&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Standard Subscription Duration&lt;/th&gt;
      &lt;th&gt;Divide the row by&lt;/th&gt;
      &lt;th&gt;Same as&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;7 Days&lt;/td&gt;
      &lt;td&gt;0.23 (7 ÷ 30.4375)&lt;/td&gt;
      &lt;td&gt;multiplying by about 4.35&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;1 Month&lt;/td&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;the row as it stands&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2 Months&lt;/td&gt;
      &lt;td&gt;2&lt;/td&gt;
      &lt;td&gt;half the row&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;3 Months&lt;/td&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;a third of the row&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;6 Months&lt;/td&gt;
      &lt;td&gt;6&lt;/td&gt;
      &lt;td&gt;a sixth of the row&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;1 Year&lt;/td&gt;
      &lt;td&gt;12&lt;/td&gt;
      &lt;td&gt;a twelfth of the row&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;30.4375 is the length of an average month (365.25 ÷ 12). Treating a month as four weeks instead understates weekly plans by about 8%.&lt;/p&gt;

&lt;h2 id=&quot;a-worked-example&quot;&gt;A worked example&lt;/h2&gt;

&lt;p&gt;Made-up numbers for an app with a monthly plan and an annual plan, from one day’s report:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Row&lt;/th&gt;
      &lt;th&gt;Duration&lt;/th&gt;
      &lt;th&gt;Developer Proceeds&lt;/th&gt;
      &lt;th&gt;Active Standard Price&lt;/th&gt;
      &lt;th&gt;Calculation&lt;/th&gt;
      &lt;th&gt;MRR&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Monthly&lt;/td&gt;
      &lt;td&gt;1 Month&lt;/td&gt;
      &lt;td&gt;3.49&lt;/td&gt;
      &lt;td&gt;120&lt;/td&gt;
      &lt;td&gt;3.49 × 120 ÷ 1&lt;/td&gt;
      &lt;td&gt;418.80&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Annual, first year&lt;/td&gt;
      &lt;td&gt;1 Year&lt;/td&gt;
      &lt;td&gt;20.99&lt;/td&gt;
      &lt;td&gt;300&lt;/td&gt;
      &lt;td&gt;20.99 × 300 ÷ 12&lt;/td&gt;
      &lt;td&gt;524.75&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Annual, Rate After One Year&lt;/td&gt;
      &lt;td&gt;1 Year&lt;/td&gt;
      &lt;td&gt;25.49&lt;/td&gt;
      &lt;td&gt;80&lt;/td&gt;
      &lt;td&gt;25.49 × 80 ÷ 12&lt;/td&gt;
      &lt;td&gt;169.93&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Annual, free trial (45 active)&lt;/td&gt;
      &lt;td&gt;1 Year&lt;/td&gt;
      &lt;td&gt;n/a&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt;not counted&lt;/td&gt;
      &lt;td&gt;0.00&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;1,113.48 USD&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The 380 annual subscribers contribute more MRR than the 120 monthly ones, yet in a sales report they appear only as lumps on their renewal days. That gap is the reason MRR exists.&lt;/p&gt;

&lt;h2 id=&quot;four-decisions-that-make-two-mrr-numbers-disagree&quot;&gt;Four decisions that make two MRR numbers disagree&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Proceeds or price.&lt;/strong&gt; Customer Price is what the buyer paid, including Apple’s commission and, in many storefronts, tax. Developer Proceeds is what you are owed. Under Apple’s &lt;a href=&quot;https://developer.apple.com/app-store/subscriptions/&quot;&gt;subscription terms&lt;/a&gt; you receive 70% of the price minus applicable taxes during a subscriber’s first year of paid service and 85% after that. Members of the &lt;a href=&quot;https://developer.apple.com/app-store/small-business-program/&quot;&gt;Small Business Program&lt;/a&gt; receive 85% from the start. An MRR built on price overstates your income by the commission and any included tax. For what every money column in the sales reports holds, from Customer Price to Developer Proceeds, see &lt;a href=&quot;/journal/app-store-proceeds-vs-sales/&quot;&gt;App Store proceeds vs sales&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Who counts as paying.&lt;/strong&gt; Free trials are pipeline, not revenue. Introductory and promotional offers are the judgment call: they bring in money, but at a temporary price. Using only Active Standard Price Subscriptions gives the conservative figure, made of subscribers paying the standard price. Including discounted offers raises the number and makes it less stable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Currency.&lt;/strong&gt; Rows arrive in many proceeds currencies. Add per currency first, then convert. Apple’s &lt;a href=&quot;https://developer.apple.com/help/app-store-connect/reference/reporting/sales-and-trends-reports-availability/&quot;&gt;availability notes&lt;/a&gt; say Sales and Trends estimates USD amounts from a rolling average of the previous month’s exchange rates. Other tools use other rates, so cross-currency totals can differ slightly even from identical inputs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Time.&lt;/strong&gt; MRR is a level, like a balance, not a flow like sales. For a week or a month, average the daily values; adding thirty days of MRR produces a number thirty times too large. Apple’s availability table also lists the Subscription report’s condition as at least one auto-renewable subscription sold, introductory prices included. When a day’s report isn’t there, treat that day as missing, not as zero.&lt;/p&gt;

&lt;h2 id=&quot;why-doesnt-mrr-match-last-months-proceeds&quot;&gt;Why doesn’t MRR match last month’s proceeds?&lt;/h2&gt;

&lt;p&gt;Sales reports record an annual renewal in full on the day it renews; MRR spreads it over twelve months. A month heavy with annual renewals shows proceeds well above MRR, and the quiet month after it shows them below. One-time purchases, paid-app sales and refunds land in proceeds and never in MRR.&lt;/p&gt;

&lt;p&gt;The two sources also differ in finality. Apple describes Sales and Trends as next-day data and points to Payments and Financial Reports for final proceeds (&lt;a href=&quot;https://developer.apple.com/help/app-store-connect/view-sales-and-trends/download-and-view-reports&quot;&gt;Apple&lt;/a&gt;). Use MRR to read the direction of your subscriber base, and the financial reports to reconcile money.&lt;/p&gt;

&lt;h2 id=&quot;doesnt-app-store-connect-show-mrr-now&quot;&gt;Doesn’t App Store Connect show MRR now?&lt;/h2&gt;

&lt;p&gt;It does, in Analytics. The Subscriptions dashboard that Apple previewed at &lt;a href=&quot;https://developer.apple.com/videos/play/wwdc2025/252/&quot;&gt;WWDC25&lt;/a&gt; shows active plans, paid plans and monthly recurring revenue. Apple’s &lt;a href=&quot;https://developer.apple.com/help/app-store-connect-analytics/reference/metrics-definitions/&quot;&gt;metric definitions&lt;/a&gt; describe MRR as “revenue earned from active paid subscriptions, normalized to a monthly timeframe.” The definition doesn’t say whether revenue means proceeds or price, which exchange rates apply, or how each plan length is normalized. If your own figure and Apple’s differ, the four decisions above are where to look.&lt;/p&gt;

&lt;p&gt;In the same session Apple said two new subscription reports in the Analytics Reports API, a subscription state report and a subscription event report, will replace the older Sales and Trends subscription reports. The Sales and Trends Subscription report is still available through the API, and the formula doesn’t depend on which file the numbers arrive in.&lt;/p&gt;

&lt;h2 id=&quot;when-does-each-days-report-arrive&quot;&gt;When does each day’s report arrive?&lt;/h2&gt;

&lt;p&gt;Daily Sales and Trends reports are available the following day, generally by 8 a.m. Pacific Time (&lt;a href=&quot;https://developer.apple.com/help/app-store-connect/reference/reporting/sales-and-trends-reports-availability/&quot;&gt;Apple&lt;/a&gt;), and a report day runs from midnight to 11:59 p.m. Pacific Time (&lt;a href=&quot;https://developer.apple.com/help/app-store-connect/view-sales-and-trends/download-and-view-reports&quot;&gt;Apple&lt;/a&gt;). Daily reports are kept for one year after they become available, so anyone building a long MRR history has to store the files as they arrive.&lt;/p&gt;

&lt;h2 id=&quot;how-appmeta-pulse-calculates-it&quot;&gt;How AppMeta Pulse calculates it&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/apps/appmeta-pulse/&quot;&gt;AppMeta Pulse&lt;/a&gt; downloads the daily Subscription report through the App Store Connect API, using a key you create that stays in your Keychain. The &lt;a href=&quot;/apps/appmeta-pulse/api-access/&quot;&gt;API access page&lt;/a&gt; lists the endpoints it calls and the role the key needs. For each row, Pulse multiplies Developer Proceeds by Active Standard Price Subscriptions and divides by the number of months the plan covers: 1, 2, 3, 6 or 12, or about 0.23 for a weekly plan. Trials are counted and shown on their own; they never enter MRR. Introductory and promotional offers stay out too, because the standard-price column already excludes them.&lt;/p&gt;

&lt;p&gt;The totals are kept per proceeds currency. Conversion happens only when a number is shown, into the display currency you choose in Settings, using the European Central Bank’s monthly average rates.&lt;/p&gt;

&lt;p&gt;Where the number appears:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Subscriptions screen.&lt;/strong&gt; MRR for the newest day Apple has published, next to active subscriptions and trials, plus a By Product list with one row per subscription and plan length, showing its MRR, active subscriptions and trials.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Trends and the per-app view.&lt;/strong&gt; MRR over a period is shown as an average (Avg MRR) across the days that have a report, compared with the previous period. Days without a report are skipped, not counted as zero.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Widgets.&lt;/strong&gt; The Subscriptions widget on the Home Screen and its Lock Screen counterpart show trials, active subscribers and MRR.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pulse doesn’t forecast MRR or make Apple’s data arrive sooner. The newest day in the app is the newest day Apple has published, usually yesterday in Pacific Time. For why a quick revenue check belongs on the phone at all, see &lt;a href=&quot;/journal/read-only-revenue-on-the-iphone/&quot;&gt;the earlier post on AppMeta Pulse&lt;/a&gt;; for how it differs from &lt;a href=&quot;/alternatives/appstats/&quot;&gt;AppStats&lt;/a&gt;, &lt;a href=&quot;/alternatives/app-sales-store-reports/&quot;&gt;App Sales&lt;/a&gt; and &lt;a href=&quot;/alternatives/appfigures/&quot;&gt;Appfigures&lt;/a&gt;, the comparison pages cover each one.&lt;/p&gt;

&lt;p&gt;Whichever tool you use, write down its four decisions before comparing its MRR with anyone else’s. Two MRR figures rarely part ways over the formula.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>How to read a shogi engine evaluation (and why it is not a chess centipawn)</title>
    <link href="https://lagerland-apps.github.io/journal/reading-a-shogi-engine-evaluation/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/reading-a-shogi-engine-evaluation/</id>
    <published>2026-06-23T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">A chess player opens a shogi analysis for the first time, sees +1800, and divides by a hundred out of habit. The arithmetic almost works, since a YaneuraOu pawn is 90 points against a centipawn&apos;s 100, and the conclusion is still wrong: the same nominal material edge buys far less in a game where captured pieces come back as drops. This post walks through the whole conversion, band by band.</summary>
    <content type="html">&lt;p&gt;A chess player opens a shogi game record, runs the analysis, and sees the graph spike to &lt;strong&gt;+1800&lt;/strong&gt;. Out of chess habit they divide by a hundred and read eighteen pawns. Two moves later it is back to +200, and they conclude the engine is broken or the position is insane.&lt;/p&gt;

&lt;p&gt;The engine is fine, and the position probably is too. The division was almost right, which is the trap: a YaneuraOu pawn is 90 points, so +1800 is nearer twenty pawns than eighteen. What does not carry over is everything the number &lt;em&gt;implies&lt;/em&gt;: how likely that edge is to hold, and how far a single capture can move it in a game where captured material comes straight back.&lt;/p&gt;

&lt;p&gt;Nobody hands you a conversion table, so here is one. The reference comes first, and the argument about what an evaluation is &lt;em&gt;for&lt;/em&gt; sits at the bottom.&lt;/p&gt;

&lt;h2 id=&quot;what-is-a-shogi-engine-evaluation-exactly&quot;&gt;What is a shogi engine evaluation, exactly?&lt;/h2&gt;

&lt;p&gt;It is a single signed integer that the engine emits at the end of a search, in units it defined for itself. Under USI, the &lt;a href=&quot;http://hgm.nubati.net/usi.html&quot;&gt;Universal Shogi Interface&lt;/a&gt; adapted from chess’s UCI, the engine prints a line containing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;score cp &amp;lt;n&amp;gt;&lt;/code&gt; for a positional evaluation or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;score mate &amp;lt;n&amp;gt;&lt;/code&gt; when it has found a forced mate.&lt;/p&gt;

&lt;p&gt;Two conventions matter before you read a single digit.&lt;/p&gt;

&lt;p&gt;The sign is from the side to move. USI reports the score from the perspective of whoever is on move in the position being searched. Almost every graphical front-end flips it so that a positive number always means Black (先手, &lt;em&gt;sente&lt;/em&gt;, the first player) is better. If your numbers seem to alternate sign every ply, you are reading raw engine output and not a normalised display.&lt;/p&gt;

&lt;p&gt;The scale belongs to the engine. &lt;a href=&quot;https://github.com/yaneurao/YaneuraOu&quot;&gt;YaneuraOu&lt;/a&gt;, the strongest open-source shogi engine, inherits the material table computer shogi has used since the Bonanza and Apery lineage: a pawn is worth about 90, a rook about 990. The NNUE network that produces the evaluation departs from pure material immediately, but the &lt;em&gt;scale&lt;/em&gt; stays anchored there. That is close to a chess centipawn, 90 units per pawn against 100. Shogi evals &lt;em&gt;look&lt;/em&gt; like four-digit numbers and chess evals like small decimals only because of display convention: chess front-ends divide by a hundred before drawing anything, and shogi front-ends print the integer. Tunings shift these constants, so if you need them exact, read them in the source instead of trusting a blog.&lt;/p&gt;

&lt;h2 id=&quot;what-do-the-evaluation-bands-mean-for-a-club-player&quot;&gt;What do the evaluation bands mean for a club player?&lt;/h2&gt;

&lt;p&gt;Japanese broadcast coverage has settled on a rough set of bands, and they translate well to a club player’s decisions. The win-probability column comes from the logistic curve computer shogi uses to convert an evaluation to a win rate, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1 / (1 + e^(-eval/600))&lt;/code&gt;. The 600 comes from win-rate fitting in the elmo and YaneuraOu learning code; it is a tuning constant, not a law.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Evaluation (your side)&lt;/th&gt;
      &lt;th&gt;Rough win probability&lt;/th&gt;
      &lt;th&gt;What it usually means&lt;/th&gt;
      &lt;th&gt;What to do with it&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;0 to ±150&lt;/td&gt;
      &lt;td&gt;50-56%&lt;/td&gt;
      &lt;td&gt;Level, inside the noise of any club game.&lt;/td&gt;
      &lt;td&gt;Nothing. Do not chase it.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;±150 to ±400&lt;/td&gt;
      &lt;td&gt;56-66%&lt;/td&gt;
      &lt;td&gt;A small edge: a tempo, a better-placed silver, a marginally safer king.&lt;/td&gt;
      &lt;td&gt;Read the plan more than the number.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;±400 to ±900&lt;/td&gt;
      &lt;td&gt;66-82%&lt;/td&gt;
      &lt;td&gt;A clear advantage, usually a piece won cleanly or a castle with a hole in it.&lt;/td&gt;
      &lt;td&gt;Find the move where it moved. That move is the lesson.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;±900 to ±2000&lt;/td&gt;
      &lt;td&gt;82-97%&lt;/td&gt;
      &lt;td&gt;Winning, if you convert: a major piece up, or an attack already landing.&lt;/td&gt;
      &lt;td&gt;Study the conversion.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Beyond ±2000&lt;/td&gt;
      &lt;td&gt;97%+&lt;/td&gt;
      &lt;td&gt;Decided. The rest is bookkeeping.&lt;/td&gt;
      &lt;td&gt;Scroll back to where it crossed.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mate N&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;100%&lt;/td&gt;
      &lt;td&gt;A proof, not a magnitude.&lt;/td&gt;
      &lt;td&gt;Solve it yourself before you look.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Two caveats matter more than the table does. The boundaries are conventions: a different engine, network or search budget draws them elsewhere, and nobody has a principled reason to prefer 400 over 450. And the win probability is a &lt;em&gt;machine’s&lt;/em&gt;. Between two 1200-rated club players a +1500 position gets thrown away often enough that the number is advice and not a forecast.&lt;/p&gt;

&lt;h2 id=&quot;why-do-shogi-evaluations-swing-harder-than-chess-centipawns&quot;&gt;Why do shogi evaluations swing harder than chess centipawns?&lt;/h2&gt;

&lt;p&gt;Because a captured shogi piece stays in the game. It goes to your hand, the &lt;em&gt;mochigoma&lt;/em&gt; (持ち駒) that sit on the wooden stand beside the board called the &lt;em&gt;komadai&lt;/em&gt; (駒台), and from there it can be dropped onto almost any empty square as an entire move.&lt;/p&gt;

&lt;p&gt;A capture is a subtraction &lt;em&gt;and&lt;/em&gt; an addition in the same move, and the evaluation moves by roughly the sum of both. Using the default material constants:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Piece captured&lt;/th&gt;
      &lt;th&gt;Kanji&lt;/th&gt;
      &lt;th&gt;Its value to them&lt;/th&gt;
      &lt;th&gt;Arrives in your hand as&lt;/th&gt;
      &lt;th&gt;Approx. total swing&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Pawn&lt;/td&gt;
      &lt;td&gt;歩&lt;/td&gt;
      &lt;td&gt;90&lt;/td&gt;
      &lt;td&gt;pawn (90)&lt;/td&gt;
      &lt;td&gt;~180&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Lance&lt;/td&gt;
      &lt;td&gt;香&lt;/td&gt;
      &lt;td&gt;315&lt;/td&gt;
      &lt;td&gt;lance (315)&lt;/td&gt;
      &lt;td&gt;~630&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Knight&lt;/td&gt;
      &lt;td&gt;桂&lt;/td&gt;
      &lt;td&gt;405&lt;/td&gt;
      &lt;td&gt;knight (405)&lt;/td&gt;
      &lt;td&gt;~810&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Silver&lt;/td&gt;
      &lt;td&gt;銀&lt;/td&gt;
      &lt;td&gt;495&lt;/td&gt;
      &lt;td&gt;silver (495)&lt;/td&gt;
      &lt;td&gt;~990&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Gold&lt;/td&gt;
      &lt;td&gt;金&lt;/td&gt;
      &lt;td&gt;540&lt;/td&gt;
      &lt;td&gt;gold (540)&lt;/td&gt;
      &lt;td&gt;~1080&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Bishop&lt;/td&gt;
      &lt;td&gt;角&lt;/td&gt;
      &lt;td&gt;855&lt;/td&gt;
      &lt;td&gt;bishop (855)&lt;/td&gt;
      &lt;td&gt;~1710&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Rook&lt;/td&gt;
      &lt;td&gt;飛&lt;/td&gt;
      &lt;td&gt;990&lt;/td&gt;
      &lt;td&gt;rook (990)&lt;/td&gt;
      &lt;td&gt;~1980&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Tokin (promoted pawn)&lt;/td&gt;
      &lt;td&gt;と&lt;/td&gt;
      &lt;td&gt;540&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;pawn (90)&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;~630&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Promoted silver&lt;/td&gt;
      &lt;td&gt;成銀&lt;/td&gt;
      &lt;td&gt;540&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;silver (495)&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;~1035&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Horse (promoted bishop)&lt;/td&gt;
      &lt;td&gt;馬&lt;/td&gt;
      &lt;td&gt;945&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;bishop (855)&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;~1800&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Dragon (promoted rook)&lt;/td&gt;
      &lt;td&gt;龍&lt;/td&gt;
      &lt;td&gt;1395&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;rook (990)&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;~2385&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The bolded rows hold the most useful piece of shogi arithmetic: promoted pieces revert when captured. A tokin is worth a gold to the player who owns it and only a pawn to the player who takes it. That asymmetry is why building tokin is such a cheap, strong plan, and why losing one hurts you six times more than it helps your opponent.&lt;/p&gt;

&lt;p&gt;Put the numbers together and winning a silver cleanly moves the evaluation about 990 points, which on the same scale is eleven pawns. In chess, winning a bishop moves you three pawns and you are pleased. In shogi, winning a silver drops you from “level” into the “winning” band in one move, and the engine is reporting the game correctly when it shows that.&lt;/p&gt;

&lt;p&gt;The other half of the answer is what &lt;em&gt;does not&lt;/em&gt; happen. Chess evaluations settle because material leaves and positions simplify toward technically drawn endings. Shogi has no such drain: trades load both komadai and sharpen the position. Shogi also has no stalemate draw and no draw by insufficient material. The only two draw mechanisms are &lt;em&gt;sennichite&lt;/em&gt;, the fourfold repetition that gets replayed with colours swapped, and the rare double-entering-king impasse called &lt;em&gt;jishogi&lt;/em&gt; (&lt;a href=&quot;https://en.wikipedia.org/wiki/Shogi&quot;&gt;both are laid out on Wikipedia’s shogi page&lt;/a&gt;). An eval near zero in shogi means “unclear”, not “heading for a draw”.&lt;/p&gt;

&lt;p&gt;Side by side:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; &lt;/th&gt;
      &lt;th&gt;Chess (Stockfish)&lt;/th&gt;
      &lt;th&gt;Shogi (YaneuraOu)&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Unit shown&lt;/td&gt;
      &lt;td&gt;Centipawns, normalised in &lt;a href=&quot;https://github.com/official-stockfish/Stockfish&quot;&gt;modern Stockfish&lt;/a&gt; so +1.00 is roughly a 50% win probability&lt;/td&gt;
      &lt;td&gt;Engine points on a table where a pawn is about 90&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Captured material&lt;/td&gt;
      &lt;td&gt;Leaves the game&lt;/td&gt;
      &lt;td&gt;Goes to the capturer’s hand&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Swing of a clean capture&lt;/td&gt;
      &lt;td&gt;About the piece’s value&lt;/td&gt;
      &lt;td&gt;About twice the piece’s value&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Legal moves in a typical middlegame&lt;/td&gt;
      &lt;td&gt;Roughly 35&lt;/td&gt;
      &lt;td&gt;Roughly 80-90 (&lt;a href=&quot;https://en.wikipedia.org/wiki/Game_complexity&quot;&gt;game-complexity figures&lt;/a&gt;)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;What ten pawns of material is worth&lt;/td&gt;
      &lt;td&gt;A decided game&lt;/td&gt;
      &lt;td&gt;About 82% win probability on the standard curve&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Effect of trades&lt;/td&gt;
      &lt;td&gt;Simplification toward drawn endings&lt;/td&gt;
      &lt;td&gt;Sharpening, with fuller hands&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Forced mate&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;score mate N&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;score mate N&lt;/code&gt;, same protocol shape&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h3 id=&quot;why-is-a-piece-in-hand-worth-more-than-the-same-piece-on-the-board&quot;&gt;Why is a piece in hand worth more than the same piece on the board?&lt;/h3&gt;

&lt;p&gt;The material table gives one value per piece, but the two states are not equal, and the NNUE network, which is not a material table, prices the difference where the table cannot.&lt;/p&gt;

&lt;p&gt;A piece in hand has no travel time. A knight on your second rank needs several moves to matter; a knight in hand can arrive on any legal square in one move.&lt;/p&gt;

&lt;p&gt;It has not committed to anything. A silver on the board is an argument about one part of the board. A silver in hand threatens every weak square at once, and your opponent has to answer all of them.&lt;/p&gt;

&lt;p&gt;It is not blocking your own pieces, which counts for a lot on a 9x9 board where all nine of your pawns start on one unbroken rank.&lt;/p&gt;

&lt;p&gt;The effect is strongest for the two pieces that can only move forward. A lance or a knight stuck behind your own lines is close to dead weight, since, as &lt;a href=&quot;/journal/making-shogi-readable-without-kanji/&quot;&gt;the piece guide explains&lt;/a&gt;, neither can ever turn around. The same lance in hand drops deep in enemy territory, aimed at a castle. The evaluation reflects that change even though the material table does not.&lt;/p&gt;

&lt;p&gt;The drop restrictions are worth memorising, because the engine has already accounted for them and you have not: no two of your unpromoted pawns on one file (&lt;em&gt;nifu&lt;/em&gt;), no pawn drop that delivers immediate checkmate (&lt;em&gt;uchifuzume&lt;/em&gt;), and no drop onto a square where the piece would have no legal move.&lt;/p&gt;

&lt;h2 id=&quot;what-does-a-mate-score-mean-in-shogi&quot;&gt;What does a mate score mean in shogi?&lt;/h2&gt;

&lt;p&gt;It means the engine has stopped estimating. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;score mate 7&lt;/code&gt; says “there is a forced mate, and here is the proof, seven moves long”, which is a different statement from “very good”. Three consequences follow.&lt;/p&gt;

&lt;p&gt;It is off the eval scale. Mate in 11 is not worse than mate in 3; both are 100%. Engines store mate as a sentinel near the top of their integer range, so a bare five-digit figure in a front-end is a mate flag leaking through as a number.&lt;/p&gt;

&lt;p&gt;A negative mate score is the one to read. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;score mate -5&lt;/code&gt; means &lt;em&gt;you&lt;/em&gt; are being mated in five, and it is the most instructive line any shogi engine hands you, because it usually starts with a drop you never considered.&lt;/p&gt;

&lt;p&gt;An engine mate is not a tsume. &lt;a href=&quot;https://en.wikipedia.org/wiki/Tsume_shogi&quot;&gt;Tsume-shogi&lt;/a&gt; is a strict problem form: every attacking move must be a check, the defender resists as long as possible, and every piece in hand must be used. Xiangqi has the same form without pieces in hand, the consecutive-check mate (连将杀); &lt;a href=&quot;/journal/xiangqi-mate-problems-from-classical-manuals/&quot;&gt;here is how Xiangqiful checked 902 of them&lt;/a&gt;. An engine’s forced mate has none of those constraints. Nor is there any score for &lt;em&gt;hisshi&lt;/em&gt; (必至), the brinkmate where mate is unavoidable next move but not yet forced by checks, and club games are decided in that gap constantly. The engine shows you a slightly worse number and never mentions that the game was over.&lt;/p&gt;

&lt;h2 id=&quot;how-much-depth-does-a-club-player-actually-need&quot;&gt;How much depth does a club player actually need?&lt;/h2&gt;

&lt;p&gt;I have argued the general case elsewhere: &lt;a href=&quot;/journal/engine-depth-at-club-level-tune-down/&quot;&gt;engine depth at club level should be tuned down, not up&lt;/a&gt;, because analysis deeper than a player can calculate produces lines that are correct and unteachable. Shogi strengthens that argument in two ways.&lt;/p&gt;

&lt;p&gt;The first is cost. With roughly 80 to 90 legal moves in a typical position against chess’s 35, each extra ply in shogi costs more and buys less. A shogi “depth 20” and a chess “depth 20” can’t be compared, because no honest conversion exists.&lt;/p&gt;

&lt;p&gt;The second is what the extra plies contain. In chess, deeper search mostly surfaces quiet positional moves whose payoff arrives ten moves later. In shogi it mostly surfaces longer drop sequences, such as five-move nets that start with a pawn dropped on an empty file to be promoted three moves later. A club player had no chance of finding those at the board and no chance of generalising from them afterwards. The mistakes that actually decided your game are visible far shallower: the hanging silver, the knight drop that would have forked king and rook, the reflexive promotion, the edge pawn that opened your mino castle.&lt;/p&gt;

&lt;p&gt;So this post gives no ply number, unlike the chess post does for Stockfish. The right depth moves with the position, the hardware and how full the komadai are. Search deep enough to prove the mistake, then stop.&lt;/p&gt;

&lt;h2 id=&quot;where-can-i-get-a-free-shogi-engine-evaluation&quot;&gt;Where can I get a free shogi engine evaluation?&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/alternatives/lishogi/&quot;&gt;Lishogi&lt;/a&gt; is free, open source and excellent. It runs online play, gives you a server-side analysis that searches harder than any phone will, produces a shareable URL for the game, and, because it is open source, lets you read exactly what the analysis did instead of trusting a description of it. If what you want is &lt;em&gt;the number&lt;/em&gt;, on a board you can send to someone, lishogi is the answer and it costs nothing. &lt;a href=&quot;/alternatives/piyoshogi/&quot;&gt;PiyoShogi&lt;/a&gt; is also a good free app, with an analysis function and finely graded opponents. The &lt;a href=&quot;/guides/best-shogi-apps-iphone/&quot;&gt;honest guide to shogi apps for iPhone&lt;/a&gt; covers the rest of the category, &lt;a href=&quot;/alternatives/81dojo/&quot;&gt;81Dojo&lt;/a&gt; included.&lt;/p&gt;

&lt;h2 id=&quot;what-an-evaluation-doesnt-tell-you&quot;&gt;What an evaluation doesn’t tell you&lt;/h2&gt;

&lt;p&gt;Once you can read the number, it still doesn’t tell you what to do. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-980&lt;/code&gt; is a verdict: you are losing, and roughly by how much. It does not say &lt;em&gt;why&lt;/em&gt;, which of your last thirty moves caused it, or what to practise tomorrow. An evaluation graph with a cliff in it is a crime-scene photo with no detective.&lt;/p&gt;

&lt;p&gt;Turning the verdict into a sentence is the whole job of a training app, and it is harder in shogi than in chess because the chess vocabulary does not carry over. A chess trainer has fork, pin, skewer, back-rank, discovered attack. Shogi needs categories that chess’s taxonomy lacks: the drop that would have forked, the promotion that cost you a retreat, the castle brick you removed yourself, the mating race you lost by one tempo. &lt;a href=&quot;/apps/shogiful/&quot;&gt;Shogiful&lt;/a&gt; builds its categories from scratch (missed drop tactic, wrong promotion decision, castle weakness, missed tsume, hanging piece, endgame error), turns each detected mistake into one or two sentences, and generates tomorrow’s training from whichever category keeps recurring. YaneuraOu’s NNUE network runs on the device, so there is no server, account or server-side rate limit. Free covers two full game analyses and three training puzzles a day. Premium is $1.99/month, $9.99/year, or $19.99 once, and it is the tier that raises engine depth and shows multiple candidate lines.&lt;/p&gt;

&lt;p&gt;That design has a cost. Shogiful leads with the sentence and puts the number second, and it has no online human play at all, so if you wanted the eval graph itself, deep and shareable, lishogi does it better and for free. &lt;a href=&quot;/apps/chessful/&quot;&gt;Chessful&lt;/a&gt; makes the same trade on the chess side with Stockfish, which is how I know it is a real trade and not a rationalisation: both apps give up the raw number as the headline in exchange for a sentence you can act on.&lt;/p&gt;

&lt;h2 id=&quot;tldr&quot;&gt;TL;DR&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;A shogi eval is not a centipawn, but the units are close enough to fool you. YaneuraOu anchors to a table where a pawn is about 90 against a centipawn’s 100, and shogi front-ends print the integer without dividing. Divide by roughly 90 to get pawns, then stop trusting the comparison: ten pawns is a decided chess game and an 82% shogi position.&lt;/li&gt;
  &lt;li&gt;The bands for a club player: under ±150 level, ±150-400 a small edge, ±400-900 a clear advantage, ±900-2000 winning if converted, beyond ±2000 decided. These are display conventions, and they move with the engine.&lt;/li&gt;
  &lt;li&gt;Every capture counts twice, because the piece goes to your hand. Winning a silver swings the number by about 990, eleven pawns’ worth. Promoted pieces revert when captured, so a tokin is a gold to its owner and a pawn to its taker.&lt;/li&gt;
  &lt;li&gt;In most positions a piece in hand beats the same piece on the board: it has no travel time, no positional commitment, and it threatens every weak square at once. This is most extreme for the lance and knight, which cannot turn around.&lt;/li&gt;
  &lt;li&gt;A mate score is categorical. Mate in 11 is worth exactly as much as mate in 3, and a negative mate score is the most instructive output a shogi engine produces. An engine mate is not the same as a tsume, and no engine reports hisshi at all.&lt;/li&gt;
  &lt;li&gt;More depth doesn’t make analysis more instructive. Shogi’s branching factor makes plies expensive, and what they buy are long drop sequences a club player could never have found. Search deep enough to prove the mistake, then stop.&lt;/li&gt;
&lt;/ul&gt;
</content>
  </entry>

  <entry>
    <title>How many steps a day should you aim for? What the large studies found, and how to pick a goal you&apos;ll keep</title>
    <link href="https://lagerland-apps.github.io/journal/how-many-steps-a-day-to-aim-for/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/how-many-steps-a-day-to-aim-for/</id>
    <published>2026-06-20T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Ten thousand steps started as a slogan. The large studies of step counts and health point lower, and they agree with each other more than the headlines suggest. This post covers what they measured and found, and how to turn that into a daily number you will still hit when an app you want is waiting behind it.</summary>
    <content type="html">&lt;p&gt;Most adults get the bulk of the benefit the research can see somewhere between about 6,000 and 10,000 steps a day. Where exactly depends on age, and benefits start far lower than that. The 10,000 figure came from a slogan. Most of the numbers you read about steps come from the four studies below.&lt;/p&gt;

&lt;h2 id=&quot;what-did-the-large-step-studies-find&quot;&gt;What did the large step studies find?&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Study&lt;/th&gt;
      &lt;th&gt;Who was measured&lt;/th&gt;
      &lt;th&gt;What they found&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://doi.org/10.1001/jamainternmed.2019.0899&quot;&gt;Lee et al., JAMA Internal Medicine, 2019&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;16,741 US women, average age 72, followed for about 4 years&lt;/td&gt;
      &lt;td&gt;About 4,400 steps a day was linked to lower mortality than about 2,700. Risk kept falling with more steps until about 7,500 a day, then levelled off&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://doi.org/10.1001/jama.2020.1382&quot;&gt;Saint-Maurice et al., JAMA, 2020&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;4,840 US adults aged 40 and over, followed for about 10 years&lt;/td&gt;
      &lt;td&gt;Compared with 4,000 steps a day, 8,000 was linked to about half the risk of death from any cause (hazard ratio 0.49), and 12,000 to about a third (0.35)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://doi.org/10.1016/S2468-2667(21)00302-9&quot;&gt;Paluch et al., Lancet Public Health, 2022&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;47,471 adults pooled from 15 cohorts&lt;/td&gt;
      &lt;td&gt;Risk fell with more steps until about 6,000 to 8,000 a day in adults 60 and over, and 8,000 to 10,000 in adults under 60, then levelled off&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://doi.org/10.1016/S2468-2667(25)00164-1&quot;&gt;Ding et al., Lancet Public Health, 2025&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;57 studies from 35 cohorts&lt;/td&gt;
      &lt;td&gt;Curves bent at around 5,000 to 7,000 steps for all-cause mortality, new cardiovascular disease, dementia and falls. 7,000 steps a day was linked to 47% lower all-cause mortality than 2,000&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Two cautions apply to every row. All four are observational: people who walk more differ from people who don’t in ways no adjustment fully captures, and Ding’s team names residual confounding among their own limitations. And in the two US studies, steps were measured once, with a research device worn for about a week at the start, not tracked for years. The numbers show where the curve bends. They are no guarantee that a given dose produces an outcome.&lt;/p&gt;

&lt;p&gt;They still agree on the shape: more steps go with lower risk, the steepest gains come early, and the curve flattens somewhere in the high thousands. Saint-Maurice’s study is the one that still saw lower risk at 12,000 than at 8,000; the pooled analyses mostly saw the flattening sooner.&lt;/p&gt;

&lt;h2 id=&quot;where-did-10000-steps-come-from&quot;&gt;Where did 10,000 steps come from?&lt;/h2&gt;

&lt;p&gt;It did not come from a study. In a 2004 review, &lt;a href=&quot;https://doi.org/10.2165/00007256-200434010-00001&quot;&gt;Tudor-Locke and Bassett&lt;/a&gt; traced the figure to Japanese walking clubs and a business slogan from more than three decades earlier. They proposed rough bands for healthy adults that are still quoted:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Steps a day&lt;/th&gt;
      &lt;th&gt;Their label&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Under 5,000&lt;/td&gt;
      &lt;td&gt;Sedentary&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;5,000 to 7,499&lt;/td&gt;
      &lt;td&gt;Low active&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;7,500 to 9,999&lt;/td&gt;
      &lt;td&gt;Somewhat active&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;10,000 or more&lt;/td&gt;
      &lt;td&gt;Active&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Over 12,500&lt;/td&gt;
      &lt;td&gt;Highly active&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The same review noted that 10,000 may not be sustainable for some groups, including older adults and people living with chronic disease, and pointed to goals set relative to a person’s own starting point as a promising alternative. Twenty-one years later, Ding’s meta-analysis landed in a similar place: 10,000 can still be a target for people who are already active, while 7,000 may be more realistic for many.&lt;/p&gt;

&lt;h2 id=&quot;does-pace-matter-or-only-the-total&quot;&gt;Does pace matter, or only the total?&lt;/h2&gt;

&lt;p&gt;Mostly the total. In Lee’s study and in Saint-Maurice’s, the measures of how fast people walked were linked to lower mortality at first, but once total steps were taken into account, most of those links were no longer clear. Paluch’s meta-analysis found one exception that held: the fastest 30 minutes of the day still showed a link after adjusting for the total, while time spent above 100 steps a minute did not.&lt;/p&gt;

&lt;p&gt;For a sense of what brisk means, the &lt;a href=&quot;https://doi.org/10.1186/s12966-019-0769-6&quot;&gt;CADENCE-Adults study&lt;/a&gt; measured treadmill walkers aged 21 to 40 and set 100 steps a minute as a practical threshold for moderate intensity and 130 for vigorous. Pace may add something, but get the daily total right first.&lt;/p&gt;

&lt;h2 id=&quot;how-long-does-each-goal-take&quot;&gt;How long does each goal take?&lt;/h2&gt;

&lt;p&gt;At about 110 steps a minute, a brisk walk, here is how long each goal takes as a single continuous walk:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Daily goal&lt;/th&gt;
      &lt;th&gt;Continuous walking at 110 steps a minute&lt;/th&gt;
      &lt;th&gt;Where it sits in the research&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;4,000&lt;/td&gt;
      &lt;td&gt;about 35 minutes&lt;/td&gt;
      &lt;td&gt;Just under the roughly 4,400 that Lee linked to lower mortality than about 2,700 in older women&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;7,000&lt;/td&gt;
      &lt;td&gt;about 65 minutes&lt;/td&gt;
      &lt;td&gt;Ding’s comparison point: 47% lower all-cause mortality than 2,000&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;8,000&lt;/td&gt;
      &lt;td&gt;about 75 minutes&lt;/td&gt;
      &lt;td&gt;Inside Paluch’s flattening range for adults over 60; the bottom of it for under 60&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;10,000&lt;/td&gt;
      &lt;td&gt;about 90 minutes&lt;/td&gt;
      &lt;td&gt;The top of Paluch’s range for adults under 60&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;12,000&lt;/td&gt;
      &lt;td&gt;about 110 minutes&lt;/td&gt;
      &lt;td&gt;Still lower risk than 8,000 in Saint-Maurice’s US sample&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Those minutes overstate the effort, because a daily total counts every step in the kitchen, the office, and the shop. The deliberate part is the gap between your goal and what an ordinary day already gives you. If you have a heart condition, an injury or another reason to be careful with exercise, ask a doctor before you tie anything to an activity target.&lt;/p&gt;

&lt;h2 id=&quot;how-do-you-pick-a-goal-youll-keep&quot;&gt;How do you pick a goal you’ll keep?&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Find your baseline.&lt;/strong&gt; The Steps chart in the Health app shows a daily average for the last week or month. Start from that number, whatever it is.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Set the goal one walk above it.&lt;/strong&gt; A goal you reach without trying does nothing, and one you only reach on your best days locks you out most of the time. Aim for a number that an ordinary day reaches only if you add one deliberate walk.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Raise it when it gets easy.&lt;/strong&gt; Moving up after a few weeks of hitting it costs little; starting too high usually ends in quitting.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Plan for the days that differ.&lt;/strong&gt; A desk day and a Saturday rarely produce the same count, so it can make sense to give them different goals.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Step count is a weak number to read for health day to day; it moves with where your phone was and what kind of day it was (&lt;a href=&quot;/journal/apple-health-metrics-worth-interpreting/&quot;&gt;more on that&lt;/a&gt;). As a target it works better, because a daily total is exactly what these studies measured.&lt;/p&gt;

&lt;h2 id=&quot;how-earnlock-uses-the-number&quot;&gt;How EarnLock uses the number&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/apps/earnlock/&quot;&gt;EarnLock&lt;/a&gt; keeps the apps you choose shielded until you reach a daily activity goal, so the goal you pick decides whether it feels like a fair price or a wall. &lt;a href=&quot;/journal/unlock-cost-outside-the-app/&quot;&gt;The argument for paying in movement&lt;/a&gt; is a separate post; this is how the goal itself works.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Three presets and a custom number.&lt;/strong&gt; Onboarding offers Light (4,000 steps), Standard (8,000, selected by default) and Challenge (12,000), each with a walking-time estimate based on 110 steps a minute rounded to five minutes: about 35, 75 and 110 minutes. A custom number can be set later from the goal settings.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Steps, or Apple’s own activity measures.&lt;/strong&gt; Steps is the free goal. Premium adds active minutes, which is Apple’s Exercise time, the green ring that &lt;a href=&quot;https://support.apple.com/guide/watch/track-daily-activity-apd3bf6d85a6/watchos&quot;&gt;Apple describes&lt;/a&gt; as minutes of brisk activity (presets 20, 30 and 45), and active energy (150, 300 and 500 kcal).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;One total per day, from Apple Health.&lt;/strong&gt; EarnLock asks HealthKit for today’s total since local midnight. HealthKit’s statistics queries &lt;a href=&quot;https://developer.apple.com/documentation/healthkit/hkstatistics&quot;&gt;merge data from all sources&lt;/a&gt; before adding it up, and Health &lt;a href=&quot;https://support.apple.com/en-us/108779&quot;&gt;ranks overlapping sources&lt;/a&gt;, so steps your iPhone and Apple Watch both counted aren’t counted twice. The Apple Watch app reads Health on the wrist, so the count is there on a walk without the phone.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The shield shows the gap.&lt;/strong&gt; A blocked app shows how many steps are still needed. If the shield’s copy of your count is too old to trust, it asks you to open the app and shows no number.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The day resets at midnight.&lt;/strong&gt; Reach the goal and the apps stay open until local midnight; then the count starts again from zero.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Raising is free; lowering waits.&lt;/strong&gt; You can raise the goal at any time. Lowering it starts a 24-hour cooldown before it can be lowered again. Premium has an optional bypass, usable once every seven days.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Different goals for different days.&lt;/strong&gt; Premium schedules can swap in Light, Standard or Challenge for chosen days and hours, which is the weekend-versus-desk-day point above.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;A week to calibrate.&lt;/strong&gt; For the first seven days nothing is blocked. EarnLock records how often the goal would have stopped you, so you can adjust before it starts to cost anything.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some step apps sell screen time by the step; &lt;a href=&quot;/alternatives/steppin/&quot;&gt;Steppin&lt;/a&gt;, for example, pays out minutes per hundred steps. EarnLock’s threshold asks for one daily total, which is the unit all of the studies above used.&lt;/p&gt;

&lt;p&gt;If you don’t know where to start, take the Health app’s daily average, add a walk, and round to the nearest preset. Standard’s 8,000 sits where the pooled studies see the curve start to flatten for most adults. Light’s 4,000 is meant as a starting point for someone with a much lower baseline.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>What actually belongs in your pet&apos;s medical record (and who asks for what)</title>
    <link href="https://lagerland-apps.github.io/journal/pet-medical-records-what-to-keep/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/pet-medical-records-what-to-keep/</id>
    <published>2026-06-14T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Your vet has a record. It is their record of their visits, and it stops at the door of their practice. The record that matters is the one you can produce yourself, at 11pm in an emergency clinic across town or at a kennel that will not take your dog without proof of a Bordetella shot. This post covers what belongs in it and who asks for which part.</summary>
    <content type="html">&lt;p&gt;Ask ten owners where their dog’s vaccination record is and most will say some version of “the vet has it.” That is true, and it doesn’t help much. The vet has &lt;em&gt;their&lt;/em&gt; record of &lt;em&gt;their&lt;/em&gt; visits. It does not include the shot the shelter gave before you adopted, or the course of antibiotics from the emergency hospital on the far side of town, or the weight you took at home last month, or the microchip registry your pet was enrolled with by a rescue in another country.&lt;/p&gt;

&lt;p&gt;The other common answer is the folder: a manila envelope in a kitchen drawer with fourteen pieces of paper in it, filed in the order they arrived. It is a real record, and it fails when it is needed, because emergencies do not happen at home.&lt;/p&gt;

&lt;p&gt;First the reference: what a pet’s medical record is made of, and who asks for which part.&lt;/p&gt;

&lt;h2 id=&quot;what-belongs-in-a-pets-medical-record&quot;&gt;What belongs in a pet’s medical record?&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Category&lt;/th&gt;
      &lt;th&gt;What to keep&lt;/th&gt;
      &lt;th&gt;Who asks for it&lt;/th&gt;
      &lt;th&gt;How often it changes&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Vaccinations&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Vaccine name, date given, date due, product and lot if printed, issuing vet&lt;/td&gt;
      &lt;td&gt;Kennels, groomers, daycare, a new vet, travel authorities, some landlords and insurers&lt;/td&gt;
      &lt;td&gt;One to three events a year&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Parasite prevention&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Flea and tick product, heartworm preventive, deworming: name, dose, dates&lt;/td&gt;
      &lt;td&gt;Your vet at the annual exam; kennels and groomers ask about fleas&lt;/td&gt;
      &lt;td&gt;Monthly for most products&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Medications&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Drug name, strength, dose, frequency, start and stop dates, prescriber&lt;/td&gt;
      &lt;td&gt;Every clinician, and most urgently an emergency vet who does not know your pet&lt;/td&gt;
      &lt;td&gt;Whenever treatment changes&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Weight history&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Dated weights, ideally including home weigh-ins&lt;/td&gt;
      &lt;td&gt;Every vet visit, since almost all drug dosing is by weight&lt;/td&gt;
      &lt;td&gt;Every visit, plus whenever you weigh at home&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Allergies and adverse reactions&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;What the reaction was to, what happened, how it was treated&lt;/td&gt;
      &lt;td&gt;Every clinician. In an emergency this is the most useful line in the record&lt;/td&gt;
      &lt;td&gt;Rarely, and each entry is permanent&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Microchip number and registry&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;The 9, 10 or 15-digit number, the registry holding it, your current contact details&lt;/td&gt;
      &lt;td&gt;Shelters and vets scanning a found animal, import authorities&lt;/td&gt;
      &lt;td&gt;Number never; your contact details every time you move&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Surgeries and procedures&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Procedure, date, surgeon, anaesthetic protocol and any complications&lt;/td&gt;
      &lt;td&gt;A new vet, a referral surgeon, an insurer&lt;/td&gt;
      &lt;td&gt;A handful of times in a life&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Chronic conditions&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Diagnosis, date, current management plan&lt;/td&gt;
      &lt;td&gt;Every clinician; emergency vets first&lt;/td&gt;
      &lt;td&gt;Slowly, but the plan changes often&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Lab and imaging results&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Bloodwork, urinalysis, radiograph and ultrasound reports, with dates&lt;/td&gt;
      &lt;td&gt;Any vet comparing today’s values to last year’s&lt;/td&gt;
      &lt;td&gt;Per test&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Insurance policy and claims&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Insurer, policy number, start date, exclusions, claim history&lt;/td&gt;
      &lt;td&gt;The insurer; the clinic if it bills directly&lt;/td&gt;
      &lt;td&gt;At renewal&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Diet&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Current food and brand, amount, feeding times, treats, known intolerances&lt;/td&gt;
      &lt;td&gt;Boarding facilities, sitters, and vets investigating weight or GI problems&lt;/td&gt;
      &lt;td&gt;Occasionally&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Practice contact details&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Your clinic, its after-hours emergency hospital, the local poison line&lt;/td&gt;
      &lt;td&gt;You, at 2am, when you cannot think straight&lt;/td&gt;
      &lt;td&gt;Rarely; verify once a year&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Three of those are left out of almost every home record, and they cost you most when they’re missing. One is the adverse-reaction line, because nobody writes down the thing that went wrong two years ago. Another is the registry behind the microchip number, because the number alone is meaningless without knowing which database holds it. AAHA’s &lt;a href=&quot;https://www.aaha.org/for-veterinary-professionals/microchip-registry-lookup-tool-aaha-find-your-pets-microchip-registry/&quot;&gt;universal pet microchip lookup tool&lt;/a&gt; exists to answer that question, but it will not help if your contact details in that registry are three addresses out of date. The third is the after-hours hospital, which people tend to look up for the first time in the worst ten minutes of the year.&lt;/p&gt;

&lt;h2 id=&quot;which-documents-does-each-situation-need&quot;&gt;Which documents does each situation need?&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Situation&lt;/th&gt;
      &lt;th&gt;What they ask for&lt;/th&gt;
      &lt;th&gt;Who issues it&lt;/th&gt;
      &lt;th&gt;Lead time&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Routine visit, your own vet&lt;/td&gt;
      &lt;td&gt;Nothing on paper. Know the current weight, every medication and dose, and what has changed since last time&lt;/td&gt;
      &lt;td&gt;Not needed&lt;/td&gt;
      &lt;td&gt;None&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Emergency or after-hours at a practice that is not yours&lt;/td&gt;
      &lt;td&gt;Current medications and doses, allergies and past reactions, chronic diagnoses, recent lab results, current weight, your vet’s name&lt;/td&gt;
      &lt;td&gt;You&lt;/td&gt;
      &lt;td&gt;None. It has to already exist&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Boarding kennel&lt;/td&gt;
      &lt;td&gt;Proof of vaccination (typically rabies plus a distemper-adenovirus-parvovirus combination and usually Bordetella for dogs; rabies plus FVRCP for cats), flea and tick status, medications with written dosing, emergency contact&lt;/td&gt;
      &lt;td&gt;Your vet’s certificate&lt;/td&gt;
      &lt;td&gt;Days to weeks; many require the shot a set number of days before arrival&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Groomer or daycare&lt;/td&gt;
      &lt;td&gt;Usually rabies proof; many also ask for Bordetella&lt;/td&gt;
      &lt;td&gt;Your vet&lt;/td&gt;
      &lt;td&gt;Often same-day&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Transfer to a new vet&lt;/td&gt;
      &lt;td&gt;Full history: vaccination record, lab and imaging results, surgical and anaesthesia reports, current prescriptions&lt;/td&gt;
      &lt;td&gt;Your old clinic, on written request&lt;/td&gt;
      &lt;td&gt;A few days&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Pet insurance claim&lt;/td&gt;
      &lt;td&gt;Itemised invoice, the clinical notes for that visit, and often a year or more of prior history to test pre-existing exclusions&lt;/td&gt;
      &lt;td&gt;The treating clinic&lt;/td&gt;
      &lt;td&gt;Days&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Domestic travel&lt;/td&gt;
      &lt;td&gt;Airline and carrier policy, which commonly means a health certificate issued by a vet within a short window before travel&lt;/td&gt;
      &lt;td&gt;An accredited vet&lt;/td&gt;
      &lt;td&gt;Days; the carrier sets the window, so check the policy first&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;International travel&lt;/td&gt;
      &lt;td&gt;Set by the &lt;strong&gt;destination country&lt;/strong&gt;: an official export health certificate, microchip, rabies vaccination in a prescribed order, sometimes a rabies antibody titre and a waiting period&lt;/td&gt;
      &lt;td&gt;Your government’s authority: &lt;a href=&quot;https://www.aphis.usda.gov/pet-travel/pet-travel-process-overview&quot;&gt;USDA APHIS&lt;/a&gt; in the US, &lt;a href=&quot;https://www.gov.uk/taking-your-pet-abroad&quot;&gt;GOV.UK&lt;/a&gt; in Great Britain&lt;/td&gt;
      &lt;td&gt;Weeks to months&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Take the international row seriously, and don’t take pet-travel rules from a blog post, including this one. The requirements depend on the pair of countries, they change, and if you get them wrong your animal can be refused at the border. Start at the government authority. The US also has separate rules for bringing a dog &lt;em&gt;into&lt;/em&gt; the country, run by the &lt;a href=&quot;https://www.cdc.gov/importation/dogs/index.html&quot;&gt;CDC&lt;/a&gt;, which since August 2024 has required all imported dogs to be microchipped and at least six months old.&lt;/p&gt;

&lt;h2 id=&quot;core-vs-non-core-vaccines&quot;&gt;Core vs non-core vaccines&lt;/h2&gt;

&lt;p&gt;This section covers the categories only. Intervals are set by your veterinarian and, for rabies, by local law, which varies by country, state and municipality. Nothing here is veterinary advice. The week-by-week timing the guidelines describe for puppies and kittens is laid out in &lt;a href=&quot;/journal/puppy-and-kitten-vaccination-schedule/&quot;&gt;puppy and kitten vaccination schedules&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The category system comes from the &lt;a href=&quot;https://wsava.org/global-guidelines/vaccination-guidelines/&quot;&gt;WSAVA Vaccination Guidelines Group&lt;/a&gt;, which publishes global guidance, and from two regional bodies in the US: the &lt;a href=&quot;https://www.aaha.org/resources/2022-aaha-canine-vaccination-guidelines/&quot;&gt;AAHA canine vaccination guidelines&lt;/a&gt; for dogs and the &lt;a href=&quot;https://catvets.com/resource/aaha-aafp-feline-vaccination-guidelines/&quot;&gt;2020 AAHA/AAFP feline vaccination guidelines&lt;/a&gt; for cats.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; &lt;/th&gt;
      &lt;th&gt;Dogs&lt;/th&gt;
      &lt;th&gt;Cats&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Core&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Distemper (CDV), adenovirus (CAV-2), parvovirus (CPV), usually combined as DAPP or DHPP, plus rabies where required by law, and leptospirosis for most US dogs under AAHA’s guidelines as updated in 2024&lt;/td&gt;
      &lt;td&gt;Panleukopenia (FPV), herpesvirus (FHV-1), calicivirus (FCV), combined as FVRCP, plus rabies where required by law, and FeLV for kittens&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Non-core, by risk&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Bordetella, canine influenza, Lyme, and regional options such as rattlesnake vaccine&lt;/td&gt;
      &lt;td&gt;FeLV for adult cats based on exposure, Chlamydia felis, Bordetella&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Legally driven&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Rabies, in most jurisdictions, with the interval fixed by statute instead of by your vet&lt;/td&gt;
      &lt;td&gt;Rabies, same&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The “core” list changes over time. In a 2024 update to its 2022 canine guidelines, AAHA moved the leptospirosis vaccine to core for most dogs in the US, having previously classed it as non-core. &lt;a href=&quot;https://www.aaha.org/newstat/publications/leptospirosis-vaccination-recommended-to-be-core-for-most-dogs/&quot;&gt;AAHA’s own announcement&lt;/a&gt; is the primary source, and the classification applies to the US, not globally. Because of changes like this one, check the current guideline instead of trusting anything written on a fixed date, including this table.&lt;/p&gt;

&lt;h2 id=&quot;why-does-the-paper-folder-fail&quot;&gt;Why does the paper folder fail?&lt;/h2&gt;

&lt;p&gt;It fails for two reasons. The obvious one is location. The folder lives at home; the emergency happens in a car park, on a walk, at a kennel, in a clinic you have never been to. A record you cannot reach is no use to anyone.&lt;/p&gt;

&lt;p&gt;The second is structure, and it does more damage. A folder is append-only and unsorted. “When was the last lepto booster?” requires reading every sheet in it. “Has she ever reacted to a vaccine?” requires remembering that the reaction was written on the back of a discharge note from 2023. The paper is a pile of source documents. A vet wants the answer, in a form they can scan in seconds while doing four other things.&lt;/p&gt;

&lt;p&gt;Photos of documents in a camera roll fail the same way. The information is there but hard to find, filed between thousands of unrelated pictures and a screenshot of a parking receipt.&lt;/p&gt;

&lt;h2 id=&quot;what-does-a-20-second-record-require&quot;&gt;What does a 20-second record require?&lt;/h2&gt;

&lt;p&gt;Here is the test. You are standing at a counter, someone in scrubs is waiting, and you have about twenty seconds before you start apologising. That test implies four constraints, and most apps fail at least one.&lt;/p&gt;

&lt;p&gt;First, it has to work with no signal and no login. Veterinary waiting rooms are often concrete boxes with terrible reception, and what ruins the twenty seconds is a login screen followed by a password reset email you cannot receive.&lt;/p&gt;

&lt;p&gt;Second, it has to produce one document. A single PDF with vaccinations, medications, weight, and history can be handed over, emailed ahead, or printed. Fourteen photos in a camera roll can’t.&lt;/p&gt;

&lt;p&gt;Third, it has to answer the question directly. “Next due” is more useful than “here is the certificate.”&lt;/p&gt;

&lt;p&gt;Fourth, it has to keep the original. A structured record that has lost its source document cannot settle a dispute with a kennel or an insurer. Keep both: the parsed fields and the scan they came from.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/apps/pawza/&quot;&gt;Pawza&lt;/a&gt; is our attempt at a record that meets all four. You photograph a vet document, Apple’s on-device Vision OCR reads the text, and, with Pro on devices with Apple Intelligence, an on-device model turns it into fields (vaccine, date given, date due, medication, dose, clinic), which you review and correct before anything is saved. It tracks weight as a trend over time, holds the microchip number, keeps the insurance policy and pet-passport documents alongside the clinical history, can schedule a local notification for each due date, and with Pro exports the whole file as one vet-visit PDF. There is no Pawza account and no Pawza server; records sit on the device in SwiftData with optional sync through your own iCloud. Our &lt;a href=&quot;/transparency/&quot;&gt;transparency page&lt;/a&gt; lists what every app declares, field by field.&lt;/p&gt;

&lt;p&gt;It has limits. It is iPhone and iPad only, and the full AI auto-fill wants Apple Intelligence on iOS 26 or later; on older devices you get OCR-assisted entry and confirm more by hand. The PDF export is a Pro feature: free covers one pet, and Pro is $2.99/month, $19.99/year or $39.99 once with Family Sharing.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/alternatives/petdesk/&quot;&gt;PetDesk&lt;/a&gt; does something Pawza cannot. It connects to participating veterinary clinics, so it can carry appointment booking and the reminders your clinic itself sends. Pawza never will, because a clinic integration needs a server to talk to and Pawza does not have one. If your vet uses PetDesk and you want to book through the app, use PetDesk. Plenty of owners run both: the clinic app for talking to the clinic, and a private record that survives switching vets.&lt;/p&gt;

&lt;p&gt;The rest of the category splits along similar lines. &lt;a href=&quot;/alternatives/11pets/&quot;&gt;11pets&lt;/a&gt; is broader and cross-platform with provider collaboration. &lt;a href=&quot;/alternatives/medika/&quot;&gt;Medika&lt;/a&gt; and &lt;a href=&quot;/alternatives/petnoter/&quot;&gt;PetNoter&lt;/a&gt; both run on Android, which we do not. &lt;a href=&quot;/alternatives/pawprint/&quot;&gt;Pawprint&lt;/a&gt;, now Great Pet Care, built its reputation on fetching records directly from participating US clinics. &lt;a href=&quot;/alternatives/vetkeep/&quot;&gt;VetKeep&lt;/a&gt; offers a conversational AI chat over your records, which requires the cloud that we deliberately do not have. Pick the trade you actually want.&lt;/p&gt;

&lt;h2 id=&quot;tldr&quot;&gt;TL;DR&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;A complete record has twelve categories&lt;/strong&gt;: vaccinations, parasite prevention, medications, weight history, allergies and reactions, microchip plus registry, surgeries, chronic conditions, labs, insurance, diet, and clinic contacts.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Different people ask for different slices.&lt;/strong&gt; Emergency vets want meds, allergies, weight and diagnoses. Kennels and groomers want proof of vaccination, often given a set number of days before arrival. Insurers want invoices plus prior history.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Core vs non-core is a risk category.&lt;/strong&gt; WSAVA, AAHA and AAFP set the categories, and your vet and local rabies law set the intervals. The categories also move, as canine leptospirosis did in AAHA’s 2024 update to its canine guidelines.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;International travel is governed by the destination country.&lt;/strong&gt; You need an official export health certificate from your government’s authority; a summary you made yourself won’t count. Start months ahead.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The record that counts is the one you can produce in twenty seconds&lt;/strong&gt; with no signal and no login, as one document, with the original scan still attached.&lt;/li&gt;
&lt;/ul&gt;
</content>
  </entry>

  <entry>
    <title>Shogi pieces in English: how to read the board without learning kanji</title>
    <link href="https://lagerland-apps.github.io/journal/making-shogi-readable-without-kanji/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/making-shogi-readable-without-kanji/</id>
    <published>2026-06-11T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Every shogi piece is the same wooden wedge stamped with a kanji character, and that one design choice stops most chess players at the door long before the rules do. Below is every piece in plain English: its name, its character, how it moves, what it promotes to, and how to read a shogi move written down.</summary>
    <content type="html">&lt;p&gt;A chess-playing friend gets curious about shogi (an anime, a YouTube clip, the strange fact that captured pieces come back fighting for the other side), installs an app, opens it, and stares at a 9×9 grid of identical wooden wedges covered in characters they cannot read. Then they close it. They never got as far as the rules.&lt;/p&gt;

&lt;p&gt;The kanji on the pieces are the wall. So before the design story, here is every piece in English, with its character, its movement, and what it turns into.&lt;/p&gt;

&lt;h2 id=&quot;the-eight-shogi-pieces-in-english&quot;&gt;The eight shogi pieces in English&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Piece (English)&lt;/th&gt;
      &lt;th&gt;Kanji&lt;/th&gt;
      &lt;th&gt;Rōmaji&lt;/th&gt;
      &lt;th&gt;How it moves&lt;/th&gt;
      &lt;th&gt;Promotes to&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;King&lt;/td&gt;
      &lt;td&gt;王 / 玉&lt;/td&gt;
      &lt;td&gt;ōshō / gyokushō&lt;/td&gt;
      &lt;td&gt;One square in any direction&lt;/td&gt;
      &lt;td&gt;Cannot promote&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Rook&lt;/td&gt;
      &lt;td&gt;飛&lt;/td&gt;
      &lt;td&gt;hisha&lt;/td&gt;
      &lt;td&gt;Any distance orthogonally (like a chess rook)&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;Dragon&lt;/strong&gt; (龍): rook + one diagonal step&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Bishop&lt;/td&gt;
      &lt;td&gt;角&lt;/td&gt;
      &lt;td&gt;kakugyō&lt;/td&gt;
      &lt;td&gt;Any distance diagonally (like a chess bishop)&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;Horse&lt;/strong&gt; (馬): bishop + one orthogonal step&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Gold general&lt;/td&gt;
      &lt;td&gt;金&lt;/td&gt;
      &lt;td&gt;kinshō&lt;/td&gt;
      &lt;td&gt;One square orthogonally, or one diagonally &lt;strong&gt;forward&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Cannot promote&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Silver general&lt;/td&gt;
      &lt;td&gt;銀&lt;/td&gt;
      &lt;td&gt;ginshō&lt;/td&gt;
      &lt;td&gt;One square straight forward, or one in any diagonal&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;+Silver&lt;/strong&gt; (成銀): moves as a gold&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Knight&lt;/td&gt;
      &lt;td&gt;桂&lt;/td&gt;
      &lt;td&gt;keima&lt;/td&gt;
      &lt;td&gt;Two forward + one to the side; &lt;strong&gt;forward only&lt;/strong&gt;, jumps over pieces&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;+Knight&lt;/strong&gt; (成桂): moves as a gold&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Lance&lt;/td&gt;
      &lt;td&gt;香&lt;/td&gt;
      &lt;td&gt;kyōsha&lt;/td&gt;
      &lt;td&gt;Any distance straight &lt;strong&gt;forward only&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;+Lance&lt;/strong&gt; (成香): moves as a gold&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Pawn&lt;/td&gt;
      &lt;td&gt;歩&lt;/td&gt;
      &lt;td&gt;fuhyō&lt;/td&gt;
      &lt;td&gt;One square straight forward; &lt;strong&gt;captures straight, not diagonally&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;Tokin&lt;/strong&gt; (と): moves as a gold&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Eight base pieces, six of which promote, all sharing one silhouette: that makes fourteen distinct things to tell apart by character alone. Chess gives every piece its own shape, so “I’ll just learn the six shapes” works there and has no equivalent here.&lt;/p&gt;

&lt;h2 id=&quot;how-the-pieces-move-for-a-chess-player&quot;&gt;How the pieces move, for a chess player&lt;/h2&gt;

&lt;p&gt;If you already play chess, the same few things will trip you up every time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The gold general.&lt;/strong&gt; It moves one step in any orthogonal direction plus the two forward diagonals: six squares, with no diagonal retreat. It matters far beyond its own movement because &lt;em&gt;four other promoted pieces all become a gold&lt;/em&gt;: promoted silver, knight, lance, and pawn move identically to it. Learn the gold’s six-square step once and you have learned the endgame behaviour of half the board.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The silver general.&lt;/strong&gt; One square straight forward, or one square in any diagonal, five squares in all. It can retreat &lt;em&gt;diagonally&lt;/em&gt; but not straight back. Promote it and it gains a gold’s straight-back step but loses its diagonal retreats, which is the kind of trade you regret when you needed the silver to come home diagonally two moves later. (Ask me how I learned to double-check that.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The knight and lance cannot turn around.&lt;/strong&gt; The knight jumps to one of two squares, two ranks forward and one file to the side, leaping over anything in between, and only forward; there is no backward knight move in shogi. The lance is a rook stripped down to a single direction: straight ahead, any distance. Once either one advances, it does not come back.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The pawn captures straight.&lt;/strong&gt; A shogi pawn moves one square forward &lt;em&gt;and captures one square forward&lt;/em&gt;, never with the diagonal capture you have wired into your hands from chess. There is no two-square first move and no en passant. Shogi has the drop instead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Drops.&lt;/strong&gt; When you capture a piece it joins &lt;em&gt;your&lt;/em&gt; hand, and you can later place it (drop it) onto any empty square as your whole move, where it fights for you. A piece changes sides several times in a normal game. Pieces always drop in their unpromoted state, and there are a few legal limits worth knowing: you can’t have two of your own unpromoted pawns on the same file (&lt;em&gt;nifu&lt;/em&gt;), you can’t drop a pawn to deliver immediate checkmate (&lt;em&gt;uchifuzume&lt;/em&gt;), and you can’t drop a piece where it would have no legal move (a pawn or lance on the last rank, a knight on the last two). Drops are also the reason &lt;a href=&quot;/journal/reading-a-shogi-engine-evaluation/&quot;&gt;a shogi engine’s evaluation swings harder than a chess engine’s&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Promotion itself is optional in the zone (the opponent’s back three ranks), except when a piece would otherwise be stuck with no move, in which case it must promote.&lt;/p&gt;

&lt;h2 id=&quot;reading-and-writing-shogi-moves-in-english&quot;&gt;Reading and writing shogi moves in English&lt;/h2&gt;

&lt;p&gt;You do not need Japanese to read a recorded game either. English shogi notation is built straight from chess algebraic, with two conventions you’ll see in the wild.&lt;/p&gt;

&lt;p&gt;Every piece is a letter: &lt;strong&gt;K&lt;/strong&gt; king, &lt;strong&gt;R&lt;/strong&gt; rook, &lt;strong&gt;B&lt;/strong&gt; bishop, &lt;strong&gt;G&lt;/strong&gt; gold, &lt;strong&gt;S&lt;/strong&gt; silver, &lt;strong&gt;N&lt;/strong&gt; knight, &lt;strong&gt;L&lt;/strong&gt; lance, &lt;strong&gt;P&lt;/strong&gt; pawn. A promoted piece gets a &lt;strong&gt;+&lt;/strong&gt; in front (&lt;strong&gt;+R&lt;/strong&gt; dragon, &lt;strong&gt;+B&lt;/strong&gt; horse, &lt;strong&gt;+P&lt;/strong&gt; tokin). A move is &lt;em&gt;piece · connector · square&lt;/em&gt;, where the connector is &lt;strong&gt;-&lt;/strong&gt; for a quiet move, &lt;strong&gt;x&lt;/strong&gt; for a capture, and &lt;strong&gt;*&lt;/strong&gt; for a drop from hand; a trailing &lt;strong&gt;+&lt;/strong&gt; means you promoted on that move, &lt;strong&gt;=&lt;/strong&gt; that you declined.&lt;/p&gt;

&lt;p&gt;Squares are file then rank. Files run &lt;strong&gt;1 to 9 right-to-left&lt;/strong&gt; from Black’s side, and ranks run top to bottom. The two systems differ only in how they letter the rank:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Hodges&lt;/strong&gt; (the standard in English shogi books, set by George Hodges in &lt;em&gt;Shogi&lt;/em&gt; magazine in 1976) uses letters &lt;strong&gt;a to i&lt;/strong&gt; for ranks: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;P-7f&lt;/code&gt; is a pawn to the 7th file, 6th rank.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Hosking&lt;/strong&gt; uses numbers &lt;strong&gt;1 to 9&lt;/strong&gt; for ranks instead, so the same square is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;76&lt;/code&gt; and the move is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;P-76&lt;/code&gt;. Hosking also writes drops with an apostrophe: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;S&apos;45&lt;/code&gt; where Hodges writes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;S*4e&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A few worked examples:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;P-7f&lt;/code&gt;&lt;/strong&gt;: pawn moves to 7f (a standard opening move).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;S*4e&lt;/code&gt;&lt;/strong&gt;: a silver, held in hand, dropped onto the empty square 4e.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bx8h+&lt;/code&gt;&lt;/strong&gt;: bishop captures on 8h and promotes to a horse.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;S3ax2b&lt;/code&gt;&lt;/strong&gt;: if you have seen the Hosking-numeric form &lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;S31x22&lt;/code&gt;&lt;/strong&gt;, it is the identical move: a silver on file 3, rank 1 capturing on file 2, rank 2.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s the whole system: piece letter, what happened, where. (Full tables, including the rarer disambiguation marks, live on the &lt;a href=&quot;https://en.wikipedia.org/wiki/Shogi_notation&quot;&gt;Wikipedia shogi-notation page&lt;/a&gt;.) To see it in use, &lt;a href=&quot;/journal/shogi-openings-for-beginners/&quot;&gt;the beginner’s guide to shogi openings&lt;/a&gt; writes out two opening lines in this notation.&lt;/p&gt;

&lt;h2 id=&quot;why-the-characters-are-the-barrier-and-why-i-didnt-just-translate-them&quot;&gt;Why the characters are the barrier, and why I didn’t just translate them&lt;/h2&gt;

&lt;p&gt;Everything above is reference. The rest is the design story behind &lt;a href=&quot;/apps/shogiful/&quot;&gt;Shogiful&lt;/a&gt;, because “just use English pieces” turns out to hide three separate problems, and most internationalised sets solve only the first.&lt;/p&gt;

&lt;p&gt;Why can’t shogi simply draw a knight as a horse the way chess does? Because the piece design carries the rules. All forty pieces are one shape and one colour, and ownership is shown by which way the wedge points, since that has to survive the drop rule: a captured piece joins your hand and comes back fighting for you. Fixed colours would show the wrong owner, and a wedge that turns around can’t. So the characters do all the identity work. 歩 is a pawn, 銀 a silver, 飛 a rook. Flip a piece on promotion and the character changes, usually to red, because promotion changes the piece’s state and keeps the piece. It is a compact system &lt;em&gt;if you read the characters&lt;/em&gt;, and a field of identical wedges if you don’t.&lt;/p&gt;

&lt;p&gt;A board you can actually read needs three things:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Identity&lt;/strong&gt;: a distinct symbol per piece that you can read at a glance. This is the easy part, and where most sets stop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Movement&lt;/strong&gt;, which matters most. A newcomer doesn’t know that a lance only goes forward, that a knight has exactly two destination squares, or that a silver can’t step sideways. Shogiful’s Western icons carry a small movement diagram in the piece itself, so the icon teaches its own legal moves. That pays off most with the gold family, where promoted silver, knight, lance, and pawn all move alike, and the icons show the resemblance so you don’t memorise four separate facts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Promotion state&lt;/strong&gt;. Traditional sets flip to red characters. A Western set needs a change just as hard to miss, more than a tint, because “did that silver promote?” is the question you can’t afford to get wrong when you’re working out whether it can retreat.&lt;/p&gt;

&lt;p&gt;Then there is the default. Shogiful shows the Western set outside Japanese locales, because a first-launch screen asking a brand-new player to choose between “traditional” and “Western” pieces asks for an informed decision before they’ve seen the board. The locale already answers the question, and the toggle in Settings is there for when they change their mind.&lt;/p&gt;

&lt;h2 id=&quot;learn-the-pieces-first-the-kanji-second&quot;&gt;Learn the pieces first, the kanji second&lt;/h2&gt;

&lt;p&gt;There is a real trade-off: the wider shogi world runs on kanji. Books, problem collections, Japanese apps, real boards and every diagram on every shogi site use kanji. A player who stays on Western pieces forever has a ceiling on what they can read.&lt;/p&gt;

&lt;p&gt;So the Western set is meant to be temporary. The piece guide is one tap from every game and shows both styles side by side, and training introduces the characters gradually. You meet 銀 &lt;em&gt;after&lt;/em&gt; you already know how a silver behaves, which is much easier than learning symbol and behaviour at once. Nobody learns chess by memorising the letters K, Q, R, B, N before their first game, yet shogi outside Japan has effectively demanded the equivalent for decades and then wondered why the game doesn’t travel.&lt;/p&gt;

&lt;h2 id=&quot;a-board-you-can-read-on-move-one&quot;&gt;A board you can read on move one&lt;/h2&gt;

&lt;p&gt;The readable board is the front door. Behind it is the reason Shogiful exists: every game analysed on-device by &lt;a href=&quot;https://github.com/yaneurao/YaneuraOu&quot;&gt;YaneuraOu&lt;/a&gt;, the strongest open-source shogi engine, with mistakes explained in plain sentences (the missed knight-drop fork, the edge pawn that cracked your castle) and training generated from your own recurring errors. None of that coaching reaches a player who bounced off the board on day one, so every other feature depends on the piece set.&lt;/p&gt;

&lt;p&gt;If you want ranked play against humans, the online platforms are the right tools, though the board there is all kanji, the problem this page is about. &lt;a href=&quot;/alternatives/lishogi/&quot;&gt;Lishogi&lt;/a&gt; (free, open-source), &lt;a href=&quot;/alternatives/81dojo/&quot;&gt;81Dojo&lt;/a&gt; (the international dojo), and &lt;a href=&quot;/alternatives/piyoshogi/&quot;&gt;PiyoShogi&lt;/a&gt; (a fine free beginner app) are the usual starting points. For the full category, offline trainers included, see &lt;a href=&quot;/guides/best-shogi-apps-iphone/&quot;&gt;our guide to the best shogi apps for iPhone&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Shogiful itself is on the &lt;a href=&quot;https://apps.apple.com/app/id6761656926&quot;&gt;App Store&lt;/a&gt; for iPhone, iPad, and Mac. It is free to try, with the full coaching loop from $1.99/month or $19.99 once. The &lt;a href=&quot;/apps/shogiful/&quot;&gt;app page&lt;/a&gt; has the methodology, a comparison with the online platforms, and six worked examples of what a plain-language shogi mistake looks like.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>How to estimate your one-rep max: Epley, Brzycki and five other formulas, worked through</title>
    <link href="https://lagerland-apps.github.io/journal/how-to-estimate-your-one-rep-max/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/how-to-estimate-your-one-rep-max/</id>
    <published>2026-06-06T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">You rarely need to grind out a true single to know roughly what it would be. A hard set of five already contains most of the answer, and there are half a dozen published formulas for pulling it out. They agree closely in the middle of the rep range and fall apart at the edges. Below is each formula, what it says about the same set, and where to stop trusting it.</summary>
    <content type="html">&lt;p&gt;The short version: take a set you pushed close to failure and run it through one of these.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Epley:&lt;/strong&gt; 1RM = weight × (1 + reps ÷ 30)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Brzycki:&lt;/strong&gt; 1RM = weight × 36 ÷ (37 − reps)&lt;/p&gt;

&lt;p&gt;A set of 100 kg for 5 comes out at 116.7 kg with Epley and 112.5 kg with Brzycki. Both are reasonable answers. The rest of this page is about why they differ, which set to feed them, and when a formula stops being worth asking.&lt;/p&gt;

&lt;h2 id=&quot;which-formulas-estimate-a-one-rep-max&quot;&gt;Which formulas estimate a one-rep max?&lt;/h2&gt;

&lt;p&gt;These are the seven you will meet in most calculators and validation studies. In each, &lt;em&gt;w&lt;/em&gt; is the weight lifted and &lt;em&gt;r&lt;/em&gt; is the number of reps.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Formula&lt;/th&gt;
      &lt;th&gt;Equation&lt;/th&gt;
      &lt;th&gt;Original source&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Epley&lt;/td&gt;
      &lt;td&gt;w × (1 + r/30)&lt;/td&gt;
      &lt;td&gt;Boyd Epley, &lt;em&gt;Boyd Epley Workout&lt;/em&gt; (1985)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Brzycki&lt;/td&gt;
      &lt;td&gt;w × 36 / (37 − r)&lt;/td&gt;
      &lt;td&gt;Matt Brzycki, &lt;a href=&quot;https://doi.org/10.1080/07303084.1993.10606684&quot;&gt;&lt;em&gt;Journal of Physical Education, Recreation &amp;amp; Dance&lt;/em&gt; (1993)&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Lander&lt;/td&gt;
      &lt;td&gt;100w / (101.3 − 2.67123r)&lt;/td&gt;
      &lt;td&gt;Jeff Lander, &lt;em&gt;NSCA Journal&lt;/em&gt; (1985)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Lombardi&lt;/td&gt;
      &lt;td&gt;w × r^0.10&lt;/td&gt;
      &lt;td&gt;Vincent Lombardi, &lt;em&gt;Beginning Weight Training&lt;/em&gt; (1989)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Mayhew et al.&lt;/td&gt;
      &lt;td&gt;100w / (52.2 + 41.9e^(−0.055r))&lt;/td&gt;
      &lt;td&gt;Mayhew and colleagues, &lt;em&gt;Journal of Applied Sport Science Research&lt;/em&gt; (1992)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;O’Conner et al.&lt;/td&gt;
      &lt;td&gt;w × (1 + 0.025r)&lt;/td&gt;
      &lt;td&gt;O’Conner, Simmons and O’Shea, &lt;em&gt;Weight Training Today&lt;/em&gt; (1989)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Wathen&lt;/td&gt;
      &lt;td&gt;100w / (48.8 + 53.8e^(−0.075r))&lt;/td&gt;
      &lt;td&gt;Dan Wathen, in the NSCA’s &lt;em&gt;Essentials of Strength Training and Conditioning&lt;/em&gt; (1994)&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;They look different, but most of them encode the same idea: each extra rep you can do with a weight means your max is a few percent higher than that weight. Brzycki’s paper puts the anchor plainly: about 10 reps at roughly 75 percent of a maximal load. Epley lands on the same point.&lt;/p&gt;

&lt;h2 id=&quot;what-does-each-formula-say-about-the-same-set&quot;&gt;What does each formula say about the same set?&lt;/h2&gt;

&lt;p&gt;This is every formula applied to 100 kg. The formulas are proportional to the weight, so for 140 kg multiply a row by 1.4.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Reps at 100 kg&lt;/th&gt;
      &lt;th&gt;Epley&lt;/th&gt;
      &lt;th&gt;Brzycki&lt;/th&gt;
      &lt;th&gt;Lander&lt;/th&gt;
      &lt;th&gt;Lombardi&lt;/th&gt;
      &lt;th&gt;Mayhew&lt;/th&gt;
      &lt;th&gt;O’Conner&lt;/th&gt;
      &lt;th&gt;Wathen&lt;/th&gt;
      &lt;th&gt;Spread&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;110.0&lt;/td&gt;
      &lt;td&gt;105.9&lt;/td&gt;
      &lt;td&gt;107.2&lt;/td&gt;
      &lt;td&gt;111.6&lt;/td&gt;
      &lt;td&gt;114.0&lt;/td&gt;
      &lt;td&gt;107.5&lt;/td&gt;
      &lt;td&gt;109.0&lt;/td&gt;
      &lt;td&gt;8.1&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;5&lt;/td&gt;
      &lt;td&gt;116.7&lt;/td&gt;
      &lt;td&gt;112.5&lt;/td&gt;
      &lt;td&gt;113.7&lt;/td&gt;
      &lt;td&gt;117.5&lt;/td&gt;
      &lt;td&gt;119.0&lt;/td&gt;
      &lt;td&gt;112.5&lt;/td&gt;
      &lt;td&gt;116.6&lt;/td&gt;
      &lt;td&gt;6.5&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;8&lt;/td&gt;
      &lt;td&gt;126.7&lt;/td&gt;
      &lt;td&gt;124.1&lt;/td&gt;
      &lt;td&gt;125.1&lt;/td&gt;
      &lt;td&gt;123.1&lt;/td&gt;
      &lt;td&gt;126.3&lt;/td&gt;
      &lt;td&gt;120.0&lt;/td&gt;
      &lt;td&gt;127.7&lt;/td&gt;
      &lt;td&gt;7.7&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;10&lt;/td&gt;
      &lt;td&gt;133.3&lt;/td&gt;
      &lt;td&gt;133.3&lt;/td&gt;
      &lt;td&gt;134.1&lt;/td&gt;
      &lt;td&gt;125.9&lt;/td&gt;
      &lt;td&gt;130.9&lt;/td&gt;
      &lt;td&gt;125.0&lt;/td&gt;
      &lt;td&gt;134.7&lt;/td&gt;
      &lt;td&gt;9.7&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;12&lt;/td&gt;
      &lt;td&gt;140.0&lt;/td&gt;
      &lt;td&gt;144.0&lt;/td&gt;
      &lt;td&gt;144.4&lt;/td&gt;
      &lt;td&gt;128.2&lt;/td&gt;
      &lt;td&gt;135.4&lt;/td&gt;
      &lt;td&gt;130.0&lt;/td&gt;
      &lt;td&gt;141.5&lt;/td&gt;
      &lt;td&gt;16.2&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;15&lt;/td&gt;
      &lt;td&gt;150.0&lt;/td&gt;
      &lt;td&gt;163.6&lt;/td&gt;
      &lt;td&gt;163.3&lt;/td&gt;
      &lt;td&gt;131.1&lt;/td&gt;
      &lt;td&gt;141.7&lt;/td&gt;
      &lt;td&gt;137.5&lt;/td&gt;
      &lt;td&gt;150.9&lt;/td&gt;
      &lt;td&gt;32.5&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;20&lt;/td&gt;
      &lt;td&gt;166.7&lt;/td&gt;
      &lt;td&gt;211.8&lt;/td&gt;
      &lt;td&gt;208.9&lt;/td&gt;
      &lt;td&gt;134.9&lt;/td&gt;
      &lt;td&gt;151.2&lt;/td&gt;
      &lt;td&gt;150.0&lt;/td&gt;
      &lt;td&gt;164.5&lt;/td&gt;
      &lt;td&gt;76.8&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;From 3 to 10 reps, the spread between the highest and lowest estimate stays under 10 kg on a 100 kg set. Epley and Brzycki meet exactly at 10 reps; below 10, Epley reads a little higher.&lt;/p&gt;

&lt;p&gt;Past 10, the curves split. Brzycki and Lander accelerate, because their denominators shrink toward zero as reps climb. Lombardi and O’Conner flatten out. By 20 reps the same set implies anything from 135 kg to 212 kg, which is not an estimate any more.&lt;/p&gt;

&lt;p&gt;At one rep, most of the formulas don’t return the weight you lifted. Epley says a 100 kg single means a 103.3 kg max. The sensible reading is to take a single at face value.&lt;/p&gt;

&lt;h2 id=&quot;why-do-the-estimates-drift-past-about-10-reps&quot;&gt;Why do the estimates drift past about 10 reps?&lt;/h2&gt;

&lt;p&gt;The clearest evidence comes from &lt;a href=&quot;https://pubmed.ncbi.nlm.nih.gov/16937972/&quot;&gt;Reynolds, Gordon and Robergs (2006)&lt;/a&gt;, who had 70 adults aged 18 to 69 test their 1, 5, 10 and 20 rep maxes on the bench press and a plate-loaded leg press. The load people could lift fell off nonlinearly as reps rose, 5-rep-max data predicted the true max best, and the authors concluded that no more than 10 repetitions should be used in linear equations to estimate a 1RM.&lt;/p&gt;

&lt;p&gt;The second reason is that the relationship between reps and load is not the same on every lift. In &lt;a href=&quot;https://pubmed.ncbi.nlm.nih.gov/17194239/&quot;&gt;Shimano and colleagues’ 2006 study&lt;/a&gt;, trained and untrained men did more reps on the back squat than on the bench press or arm curl at 60 percent of their max. The gap shrank at 80 and 90 percent. A formula fitted on one lift and applied to another is borrowing someone else’s curve, and the borrowing gets worse the lighter the load.&lt;/p&gt;

&lt;p&gt;The third reason is that a long set tests something different. Twenty reps is as much a test of how well you tolerate fatigue as of how much force you can produce once. Two lifters with the same single can have very different 20-rep maxes.&lt;/p&gt;

&lt;p&gt;The last one is about you, not the maths. Every formula assumes the set ended at or very near failure. If your set of five stopped with three reps left in the tank, the formula treats it as a five-rep max when that weight was really closer to an eight-rep max, and the estimate reads low.&lt;/p&gt;

&lt;h2 id=&quot;which-formula-should-you-use&quot;&gt;Which formula should you use?&lt;/h2&gt;

&lt;p&gt;Whichever one you will use every time. An estimated max is most useful as a trend line, and any of the mainstream formulas applied the same way to similar sets will show the same trend. Switching between them week to week manufactures progress or regression that never happened.&lt;/p&gt;

&lt;p&gt;Some habits that keep the number honest:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Feed it sets of about 3 to 8 reps, taken close to failure. That is where the formulas agree most.&lt;/li&gt;
  &lt;li&gt;Compare like with like. A 5-rep estimate this month against a 5-rep estimate last month means more than a 5-rep estimate against a 10-rep one.&lt;/li&gt;
  &lt;li&gt;Use the heaviest working set of the session, not warm-ups or back-off sets.&lt;/li&gt;
  &lt;li&gt;Treat the estimate for a lift you rarely train heavy, like a lateral raise, as a curiosity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The same formulas work in reverse, for choosing a working weight from a known max:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Reps&lt;/th&gt;
      &lt;th&gt;% of 1RM (Epley)&lt;/th&gt;
      &lt;th&gt;% of 1RM (Brzycki)&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;2&lt;/td&gt;
      &lt;td&gt;93.8&lt;/td&gt;
      &lt;td&gt;97.2&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;90.9&lt;/td&gt;
      &lt;td&gt;94.4&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;5&lt;/td&gt;
      &lt;td&gt;85.7&lt;/td&gt;
      &lt;td&gt;88.9&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;6&lt;/td&gt;
      &lt;td&gt;83.3&lt;/td&gt;
      &lt;td&gt;86.1&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;8&lt;/td&gt;
      &lt;td&gt;78.9&lt;/td&gt;
      &lt;td&gt;80.6&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;10&lt;/td&gt;
      &lt;td&gt;75.0&lt;/td&gt;
      &lt;td&gt;75.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;12&lt;/td&gt;
      &lt;td&gt;71.4&lt;/td&gt;
      &lt;td&gt;69.4&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Read it as a starting point. Given the Shimano result, expect the squat to allow more reps at a given percentage than the bench press or an arm curl, especially at lighter loads.&lt;/p&gt;

&lt;h2 id=&quot;when-should-you-test-a-true-single&quot;&gt;When should you test a true single?&lt;/h2&gt;

&lt;p&gt;When the exact number is what you need. A powerlifting meet is the obvious case. So is a program whose percentages are built on a tested max, or the end of a peaking block, when you have tapered and are fresh enough for the number to mean something.&lt;/p&gt;

&lt;p&gt;It is a poor idea when you are stalled and want reassurance, at the end of a hard training week, or when you are coming back from a layoff. A single tested tired tells you less than a good set of five tested fresh.&lt;/p&gt;

&lt;p&gt;If you do test one, the usual shape is a gradual warm-up through progressively heavier sets of fewer reps, then a small number of heavy single attempts with generous rest between them. Use safety arms or a spotter on anything that can pin you. And if you are working around an injury or a condition that affects heavy loading, get advice from a clinician or a coach who can see you lift before you go looking for a max.&lt;/p&gt;

&lt;h2 id=&quot;what-gymlogger-x-uses&quot;&gt;What GymLogger X uses&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/apps/gymlogger-x/&quot;&gt;GymLogger X&lt;/a&gt; uses Epley everywhere an estimated 1RM appears: the strength trend for each exercise, the rep-max table, and the plateau rule, which watches that trend. I picked it for the reason in the section above. It is one of the mainstream formulas, it agrees with Brzycki at 10 reps, and it is simple enough that you can check the app’s arithmetic yourself. There is no setting to switch formulas, on purpose.&lt;/p&gt;

&lt;p&gt;A few details follow from the reasoning in this post:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A logged single is its own 1RM. The app doesn’t run a single through the formula and hand you 103.3 kg for a 100 kg lift.&lt;/li&gt;
  &lt;li&gt;The rep-max table on each exercise shows your best weight at 1, 3, 5, 8, 10 and 12 reps. Slots come from sets you actually lifted where possible, and any slot the app had to estimate is labelled as an estimate.&lt;/li&gt;
  &lt;li&gt;Only a single you really did counts as an actual 1RM in that table. Until you log one, the 1RM slot shows an estimate, and the screen says so.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The plateau rule built on top of this is published in full on the &lt;a href=&quot;/apps/gymlogger-x/&quot;&gt;app page&lt;/a&gt;, and the reasoning behind making the Apple Watch the logging surface is in &lt;a href=&quot;/journal/the-strength-logger-no-one-asked-for/&quot;&gt;the post on why GymLogger X exists&lt;/a&gt;. If you are still choosing an app, the &lt;a href=&quot;/guides/workout-app-without-subscription/&quot;&gt;guide to workout apps without a subscription&lt;/a&gt; compares the field by pricing model.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>How much to tip in the US: every common situation, with the arithmetic</title>
    <link href="https://lagerland-apps.github.io/journal/how-much-to-tip-in-the-us/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/how-much-to-tip-in-the-us/</id>
    <published>2026-05-30T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">American tipping is a dozen small rules, and most of the confusion comes from not knowing which one applies. Below are a table by situation, the arithmetic for the awkward cases (pre-tax or post-tax, the bar tab, the bill that already includes a gratuity), and the source for every number.</summary>
    <content type="html">&lt;p&gt;If you are unsure how much to tip, you are in the majority. In a 2023 survey of 11,945 US adults by the &lt;a href=&quot;https://www.pewresearch.org/2023/11/09/tipping-culture-in-america-public-sees-a-changed-landscape/&quot;&gt;Pew Research Center&lt;/a&gt;, only about a third said it was extremely or very easy to know whether to tip (34%) or how much (33%). And 72% said tipping is expected in more places than it was five years earlier.&lt;/p&gt;

&lt;p&gt;The rules themselves are short. The table comes first, then the arithmetic for the cases where they get awkward.&lt;/p&gt;

&lt;h2 id=&quot;how-much-to-tip-by-situation&quot;&gt;How much to tip, by situation&lt;/h2&gt;

&lt;p&gt;The ranges are the Emily Post Institute’s, from its &lt;a href=&quot;https://emilypost.com/advice/general-tipping-guide&quot;&gt;general tipping guide&lt;/a&gt;. The last column applies them to example bills.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Situation&lt;/th&gt;
      &lt;th&gt;Usual guidance&lt;/th&gt;
      &lt;th&gt;Worked example&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Sit-down restaurant&lt;/td&gt;
      &lt;td&gt;15 to 20% of the bill before tax&lt;/td&gt;
      &lt;td&gt;$60 of food: $9 to $12&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Buffet&lt;/td&gt;
      &lt;td&gt;10% before tax&lt;/td&gt;
      &lt;td&gt;$30: $3&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Takeout&lt;/td&gt;
      &lt;td&gt;No obligation; 10% for curbside service or a large, complicated order&lt;/td&gt;
      &lt;td&gt;$45 order: $0, or $4.50&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Food delivery&lt;/td&gt;
      &lt;td&gt;10 to 15% of the bill; $2 to $5 for pizza, by size and difficulty&lt;/td&gt;
      &lt;td&gt;$32 order: $3.20 to $4.80&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Bartender&lt;/td&gt;
      &lt;td&gt;$1 to $2 per drink, or 15 to 20% of the tab&lt;/td&gt;
      &lt;td&gt;See the bar tab below&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Tip jar&lt;/td&gt;
      &lt;td&gt;No obligation; tip now and then for extra effort, or if you are a regular&lt;/td&gt;
      &lt;td&gt;Your call&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Taxi&lt;/td&gt;
      &lt;td&gt;15 to 20% of the fare, at least $1, plus $2 for the first bag and $1 for each one after&lt;/td&gt;
      &lt;td&gt;$38 fare, 2 bags: $8.70 to $10.60&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Hair stylist&lt;/td&gt;
      &lt;td&gt;15 to 20%, shared among everyone who worked on you&lt;/td&gt;
      &lt;td&gt;$70 cut: $10.50 to $14&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Hotel housekeeping&lt;/td&gt;
      &lt;td&gt;$2 to $5 per day, left daily&lt;/td&gt;
      &lt;td&gt;4 nights: $8 to $20&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Valet&lt;/td&gt;
      &lt;td&gt;$2 to $5 when the car comes back&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Bellhop&lt;/td&gt;
      &lt;td&gt;$2 for the first bag, $1 for each additional bag&lt;/td&gt;
      &lt;td&gt;3 bags: $4&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The guide covers tip jars but not the tip screens now common at counters. A screen asks the same question as a jar, so the jar row is the closest guide.&lt;/p&gt;

&lt;h2 id=&quot;why-the-restaurant-row-is-different&quot;&gt;Why the restaurant row is different&lt;/h2&gt;

&lt;p&gt;Under the federal Fair Labor Standards Act, an employer can pay a tipped worker a cash wage of $2.13 an hour and count up to $5.12 an hour of tips toward the $7.25 federal minimum wage, according to the Department of Labor’s &lt;a href=&quot;https://www.dol.gov/agencies/whd/fact-sheets/15-tipped-employees-flsa&quot;&gt;Fact Sheet #15&lt;/a&gt;. Some states, including California, Oregon and Washington, require the full state minimum wage before tips, as the Department’s &lt;a href=&quot;https://www.dol.gov/agencies/whd/state/minimum-wage/tipped&quot;&gt;state-by-state table&lt;/a&gt; shows. Where the tip credit applies, the restaurant tip is counted toward the server’s wage itself.&lt;/p&gt;

&lt;h2 id=&quot;what-americans-actually-tip&quot;&gt;What Americans actually tip&lt;/h2&gt;

&lt;p&gt;Pew asked how often people tip in different settings. The share who say they always or often tip:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Setting&lt;/th&gt;
      &lt;th&gt;Always or often tip&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Sit-down restaurant&lt;/td&gt;
      &lt;td&gt;92%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Haircut&lt;/td&gt;
      &lt;td&gt;78%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Food delivery&lt;/td&gt;
      &lt;td&gt;76%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Drink at a bar&lt;/td&gt;
      &lt;td&gt;70%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Taxi or rideshare&lt;/td&gt;
      &lt;td&gt;61%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Buying coffee&lt;/td&gt;
      &lt;td&gt;25%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Fast casual restaurant&lt;/td&gt;
      &lt;td&gt;12%&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The amounts sit lower than the etiquette range. A majority would tip 15% or less for an average meal at a sit-down restaurant, and only about a quarter would tip 20% or more. So guidance and habit overlap at 15%, and 20% is the top of the range for most people.&lt;/p&gt;

&lt;h2 id=&quot;pre-tax-or-post-tax-the-arithmetic&quot;&gt;Pre-tax or post-tax? The arithmetic&lt;/h2&gt;

&lt;p&gt;The Emily Post guide calculates the restaurant tip on the bill before tax. If you tip on the after-tax total instead, the gap is always the tip rate times the tax.&lt;/p&gt;

&lt;p&gt;Dinner for four, $148.00 of food, and a sales tax of 8% (an example rate; yours depends on where you eat): $11.84 of tax, $159.84 in total.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Tip&lt;/th&gt;
      &lt;th&gt;On $148.00 before tax&lt;/th&gt;
      &lt;th&gt;On $159.84 after tax&lt;/th&gt;
      &lt;th&gt;Difference&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;15%&lt;/td&gt;
      &lt;td&gt;$22.20&lt;/td&gt;
      &lt;td&gt;$23.98&lt;/td&gt;
      &lt;td&gt;$1.78&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;18%&lt;/td&gt;
      &lt;td&gt;$26.64&lt;/td&gt;
      &lt;td&gt;$28.77&lt;/td&gt;
      &lt;td&gt;$2.13&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;20%&lt;/td&gt;
      &lt;td&gt;$29.60&lt;/td&gt;
      &lt;td&gt;$31.97&lt;/td&gt;
      &lt;td&gt;$2.37&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;At an 18% tip and an 8% tax, tipping on the total adds 1.44% of the food bill: $2.13 here, about 53 cents a head. Neither choice is rude; it helps to pick one and use it every time.&lt;/p&gt;

&lt;h2 id=&quot;the-bill-that-already-includes-a-tip&quot;&gt;The bill that already includes a tip&lt;/h2&gt;

&lt;p&gt;Some restaurants add an automatic gratuity, often for large parties, so read the bill before you reach for a percentage. Under the Fair Labor Standards Act a compulsory charge for service is not a tip (&lt;a href=&quot;https://www.dol.gov/agencies/whd/fact-sheets/15-tipped-employees-flsa&quot;&gt;DOL Fact Sheet #15&lt;/a&gt;). The IRS lists a large dining party’s automatic gratuity as a service charge, because a tip has to be voluntary and its amount set by the customer (&lt;a href=&quot;https://www.irs.gov/newsroom/employer-reminder-reporting-tips-versus-service-charges-key-differences-between-categories-affect-employees-tax-reporting&quot;&gt;IRS fact sheet FS-2017-08&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Missing the line gets expensive. Take a party of eight with $420 of food and an 18% automatic gratuity of $75.60. Add a reflexive 20% ($84.00) on top and service has cost $159.60, or 38% of the food. You can still leave something extra for exceptional service, as long as you mean to.&lt;/p&gt;

&lt;h2 id=&quot;the-bar-tab-per-drink-or-percentage&quot;&gt;The bar tab: per drink or percentage?&lt;/h2&gt;

&lt;p&gt;The bartender row offers two rules, and which one is more generous depends on the price of the drink.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Round&lt;/th&gt;
      &lt;th&gt;$1 a drink&lt;/th&gt;
      &lt;th&gt;$2 a drink&lt;/th&gt;
      &lt;th&gt;15 to 20% of the tab&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;6 beers at $7 ($42)&lt;/td&gt;
      &lt;td&gt;$6 (14%)&lt;/td&gt;
      &lt;td&gt;$12 (29%)&lt;/td&gt;
      &lt;td&gt;$6.30 to $8.40&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;6 cocktails at $15 ($90)&lt;/td&gt;
      &lt;td&gt;$6 (7%)&lt;/td&gt;
      &lt;td&gt;$12 (13%)&lt;/td&gt;
      &lt;td&gt;$13.50 to $18.00&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The rules meet at about $10 a drink, where $1.50 to $2 is 15 to 20%. Below that, $2 a drink runs well above 20%. Above it, $1 a drink falls well under 15%, and the percentage is the rule to use.&lt;/p&gt;

&lt;h2 id=&quot;when-a-group-splits-the-tip&quot;&gt;When a group splits the tip&lt;/h2&gt;

&lt;p&gt;The tip follows the food. If everyone ordered about the same, divide the total with tip by the number of people. If not, give each person the same percentage on what they ordered: at 20%, a $16 salad carries $3.20 of tip and a $52 steak carries $10.40. The social side, who proposes what and when, is in &lt;a href=&quot;/journal/splitting-a-valentines-dinner-without-making-it-weird/&quot;&gt;how to split a Valentine’s dinner without making it weird&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;where-rightsplit-fits&quot;&gt;Where RightSplit fits&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/apps/rightsplit/&quot;&gt;RightSplit&lt;/a&gt; puts the tip on the same screen as the split. The tip control has four presets, 0%, 15%, 18% and 20%, and a slider from 0 to 30% in whole-percent steps. On an iPhone set to the US or Canada region, the first tip it suggests is 18%; in the UK it starts at 10% and in Japan at 0%. After that it remembers whatever you used last.&lt;/p&gt;

&lt;p&gt;The free equal split applies the percentage to the total amount you type. Enter the after-tax total from the dinner above and choose 18%: $188.61, which Round fairly, on by default, splits as $47.16 for one person and $47.15 for the other three, so the shares add up to the cent. That is the post-tax tip, $2.13 more than the pre-tax version. If the bill already includes a service charge, the 0% preset is the one to tap.&lt;/p&gt;

&lt;p&gt;In Pro+, item splitting gives each person the tip on what they ordered, and when a scanned receipt has tax and tip lines, RightSplit spreads both in proportion to each person’s items. There are no accounts; only the person holding the phone needs the app.&lt;/p&gt;

&lt;p&gt;RightSplit won’t choose the percentage for you. It doesn’t know whether you are at a buffet or a steakhouse, so that part comes from the table above.&lt;/p&gt;

&lt;h2 id=&quot;tldr&quot;&gt;TL;DR&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Sit-down restaurants: 15 to 20% of the bill before tax.&lt;/strong&gt; Buffets 10%. Most Americans tell Pew they would leave 15% or less.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Delivery 10 to 15%, taxis and haircuts 15 to 20%, housekeeping $2 to $5 a day, valets $2 to $5.&lt;/strong&gt; Takeout and tip jars carry no obligation.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Tipping after tax adds the tip rate times the tax:&lt;/strong&gt; $2.13 on an 18% tip for $148 of food at 8% tax.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;At the bar, $1 to $2 a drink and 15 to 20% meet at about $10 a drink.&lt;/strong&gt; On pricier cocktails, use the percentage.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;An automatic gratuity is a service charge under DOL and IRS rules.&lt;/strong&gt; Read the bill before adding 20% on top.&lt;/li&gt;
&lt;/ul&gt;
</content>
  </entry>

  <entry>
    <title>The unlock cost has to live outside the app</title>
    <link href="https://lagerland-apps.github.io/journal/unlock-cost-outside-the-app/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/unlock-cost-outside-the-app/</id>
    <published>2026-05-23T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Every screen-time blocker on the App Store has the same secret. If you tap hard enough, it folds. A short essay on why every app in this category eventually adds a tap-through escape, and what to build in its place.</summary>
    <content type="html">&lt;p&gt;Every screen-time blocker on the App Store has the same secret. If you tap hard enough, it folds.&lt;/p&gt;

&lt;p&gt;Open Opal mid-session and tap “I really need to use this.” Open one sec and wait the ten seconds. Open ScreenZen and dismiss the pause. Forest lets you give up a tree. Even Brick, which goes as far as shipping you a physical NFC tag, lets you unlock with the tag from across the room.&lt;/p&gt;

&lt;p&gt;What these apps add is friction, which is different from blocking.&lt;/p&gt;

&lt;p&gt;A blocker has a cost you cannot pay in the middle of a craving. Friction has a cost you can pay in two taps, and the design relies on the &lt;em&gt;hope&lt;/em&gt; that you won’t.&lt;/p&gt;

&lt;p&gt;App Store ratings are why every app in this category eventually adds a tap-through escape. The user sets up the blocker on a Sunday afternoon when they are calm and runs into it on a Thursday night when they are not. The Sunday version of the user wants a wall. The Thursday version wants a door. Whichever one drives the rating distribution ships in the next release.&lt;/p&gt;

&lt;p&gt;So the apps end up with a door, and it gets easier to open with every version.&lt;/p&gt;

&lt;h2 id=&quot;where-the-cost-has-to-live&quot;&gt;Where the cost has to live&lt;/h2&gt;

&lt;p&gt;If the cost of unlocking lives inside the app, the user can lower it. They wrote the PIN, set the timer, and picked the pause length. In the moment of craving none of these is an obstacle. They are notes left by an earlier self, and the current self has the credentials.&lt;/p&gt;

&lt;p&gt;The cost has to live somewhere the craving cannot reach. There are two reasonable candidates: time and the body.&lt;/p&gt;

&lt;p&gt;Time is already taken by the wait-out model that one sec and ScreenZen use. It doesn’t work, because waiting is itself a tap. The user puts the phone down, picks it back up, ten seconds have passed, and the lock is gone. They paid in attention, the same thing they were trying to protect in the first place, and the wait gives them nothing they benefit from later.&lt;/p&gt;

&lt;p&gt;The body is the other candidate. If the unlock costs steps, active minutes, or active calories, the user cannot pay it from the couch. They have to go outside, get on the floor, or move around the room. What makes the design defensible, and more than merely strict, is that the user’s life &lt;em&gt;also benefits from&lt;/em&gt; the payment. It is the only kind of unlock cost that is both real and useful.&lt;/p&gt;

&lt;p&gt;That’s what &lt;a href=&quot;/apps/earnlock/&quot;&gt;EarnLock&lt;/a&gt; does. The blocked apps stay blocked until the user hits a daily activity goal measured in Apple Health: steps in the free tier, active minutes or active energy in Premium. The user picks the goal on a calm day, and the Thursday version of the user can’t renegotiate it because there is no tap-through.&lt;/p&gt;

&lt;h2 id=&quot;why-the-shield-matters&quot;&gt;Why the shield matters&lt;/h2&gt;

&lt;p&gt;A second design choice follows from the first.&lt;/p&gt;

&lt;p&gt;By default, &lt;a href=&quot;/journal/what-an-iphone-app-can-actually-block/&quot;&gt;Apple’s Family Controls API&lt;/a&gt; renders a generic restriction screen over any app you block: &lt;em&gt;This app has been restricted by Screen Time.&lt;/em&gt; It looks like a system prompt. It tells the user nothing about what is left, how it relates to the goal, or whether the cost is reachable.&lt;/p&gt;

&lt;p&gt;EarnLock paints its own shield, with a circular progress ring, the current step count, and the exact number remaining: &lt;em&gt;Earn 2,026 more steps to unlock&lt;/em&gt;. A user who tries to open Instagram isn’t told they are restricted. They’re told they are 2,026 steps from Instagram, which is a place they can walk to.&lt;/p&gt;

&lt;p&gt;It’s a small detail with a big effect. A wall produces resentment, and a destination gets people moving. The shield is what turns the body-cost mechanic from a punishment into a price tag.&lt;/p&gt;

&lt;h2 id=&quot;where-the-failure-modes-live&quot;&gt;Where the failure modes live&lt;/h2&gt;

&lt;p&gt;Designing it this way has two real costs.&lt;/p&gt;

&lt;p&gt;The first is that on some days the user won’t hit the goal and won’t see Instagram that day. The product has to make that survivable without making it easy to undermine. EarnLock includes one math-gated emergency unlock per day: solve a real arithmetic problem, get one unlock, then nothing until midnight. The math is hard enough that you cannot solve it mid-doomscroll without breaking concentration. That door is for genuine emergencies only.&lt;/p&gt;

&lt;p&gt;The second is that streaks are dangerous in this category. If the app tells the user “you’ve blocked Instagram 47 days in a row,” they start protecting the number for its own sake, and then a sick day or a snowed-in day breaks the streak and they quit the whole thing. EarnLock ships a streak because users ask for it, but a single rest day per week protects the count, and no notification shames the user for missing a day. The streak can exist, but it can’t become the thing the user is actually optimising.&lt;/p&gt;

&lt;p&gt;(I wrote a &lt;a href=&quot;/journal/streaks-are-a-debt/&quot;&gt;separate essay about why streak counters are a debt instrument&lt;/a&gt;. The short version: any time you ship a streak, you owe the user a rest mechanism, or you’re building a guilt loop under another name.)&lt;/p&gt;

&lt;h2 id=&quot;the-shadow-week&quot;&gt;The shadow week&lt;/h2&gt;

&lt;p&gt;One more piece deserves a name, because most blockers get it wrong on day one.&lt;/p&gt;

&lt;p&gt;When a user installs a screen-time app, the app knows nothing about them yet: which apps they overuse, what time of day the urge spikes, or how much real time they would have spent if nothing blocked them. So it picks a default, usually generous and sometimes hostile, and the user leaves either because it is too strict or because it does nothing.&lt;/p&gt;

&lt;p&gt;EarnLock starts in &lt;strong&gt;shadow mode&lt;/strong&gt; for the first week. Nothing is blocked. The app watches which apps the user opens, when, and for how long. At the end of the week it shows a screen that says, in effect, &lt;em&gt;here is what you would have lost, about 30 minutes a day and 23 separate block events this week, based on your own behaviour. Enable real blocking?&lt;/em&gt; The user decides with their own data and not with a stranger’s guess about a phone they’ve never seen.&lt;/p&gt;

&lt;p&gt;I think this is the right default for any tool that proposes to change someone’s behaviour. In the first week the tool should earn the right to act, by showing it understands what is actually happening, before it acts on the user at all.&lt;/p&gt;

&lt;h2 id=&quot;why-no-account-no-server-no-sdk&quot;&gt;Why no account, no server, no SDK&lt;/h2&gt;

&lt;p&gt;The last piece is about structure.&lt;/p&gt;

&lt;p&gt;A screen-time app sees more about a user’s habits than almost any other software they install: which apps they want to avoid, how often they try to break the rules, what time of day they fail, how long their attention lasts. By a wide margin it is the most psychologically intimate dataset a phone can produce, more intimate than location, messages, or the photo library.&lt;/p&gt;

&lt;p&gt;The only safe thing to do with that data is to keep it on the device.&lt;/p&gt;

&lt;p&gt;EarnLock has no account, no sign-up screen, no analytics SDK, no advertising SDK, no third-party SDKs of any kind, and no EarnLock server anywhere. HealthKit is read on-device only and never transmitted. Family Controls hands EarnLock opaque tokens, so even &lt;em&gt;we&lt;/em&gt; cannot see which apps the user picked to block. Apple’s App Privacy nutrition label reads “Data Not Collected” for every release.&lt;/p&gt;

&lt;p&gt;Any app that sits between a user and their own behaviour should work this way. No database should know the user tried to open Instagram 47 times last Tuesday, no server should know they missed their step goal for a week in February, and no account should tie any of it to an email address. The data is intimate, and the right response to that is restraint.&lt;/p&gt;

&lt;h2 id=&quot;what-this-trades-away&quot;&gt;What this trades away&lt;/h2&gt;

&lt;p&gt;The cost of this design is reach.&lt;/p&gt;

&lt;p&gt;A screen-time app with no account cannot sync state through a third-party backend. (EarnLock uses CloudKit through the user’s own Apple ID for the iPhone-to-Watch handoff, which is the only acceptable alternative.) Without an analytics SDK it cannot run growth experiments on cohorts of strangers. And with no tap-through escape it will get some one-star reviews from people who wanted a door.&lt;/p&gt;

&lt;p&gt;I think those are the right costs to pay.&lt;/p&gt;

&lt;p&gt;A screen-time blocker that can be talked out of blocking in the moment is decoration. One that ships behavioural data to a third-party server is a study you didn’t sign up for.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/apps/earnlock/&quot;&gt;EarnLock&lt;/a&gt; takes both of those positions seriously. Free; Premium $1.99/month, $9.99/year (with a 7-day free trial), or $19.99 lifetime. Every paid tier (Monthly, Yearly, and Lifetime) is Family Sharing eligible.&lt;/p&gt;

&lt;p&gt;If you can unlock it in two taps, it isn’t a blocker.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>How the App Store keyword field works: 100 characters, commas, and the words Apple already indexes</title>
    <link href="https://lagerland-apps.github.io/journal/app-store-keyword-field-100-characters/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/app-store-keyword-field-100-characters/</id>
    <published>2026-05-16T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Customers never see the keyword field, yet it decides a lot about who finds your app. Apple&apos;s rules for it would fit on an index card, and most of the advice around it is folklore. This post covers what Apple documents, what it leaves out, and how to spend 100 characters without wasting a third of them.</summary>
    <content type="html">&lt;p&gt;The keyword field in App Store Connect is a single line of text per localization, and nobody browsing the App Store ever reads it. Apple’s search guide says keywords “help determine where your app appears in search results.” Below are its rules in one place, each with its source.&lt;/p&gt;

&lt;h2 id=&quot;what-are-the-rules-for-the-app-store-keyword-field&quot;&gt;What are the rules for the App Store keyword field?&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Rule&lt;/th&gt;
      &lt;th&gt;What Apple says&lt;/th&gt;
      &lt;th&gt;Source&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Length&lt;/td&gt;
      &lt;td&gt;100 characters total per localization (the reference page says 100 bytes)&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://developer.apple.com/app-store/product-page/&quot;&gt;Product page&lt;/a&gt;, &lt;a href=&quot;https://developer.apple.com/help/app-store-connect/reference/app-information/platform-version-information/&quot;&gt;Platform version information&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Separator&lt;/td&gt;
      &lt;td&gt;Commas, no spaces. Spaces are allowed inside a phrase: Property,House,Real Estate&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://developer.apple.com/app-store/search/&quot;&gt;App Store search&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Word length&lt;/td&gt;
      &lt;td&gt;Each keyword greater than two characters&lt;/td&gt;
      &lt;td&gt;Platform version information&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Don’t repeat&lt;/td&gt;
      &lt;td&gt;Words already in your app name, subtitle or category; the reference adds your company name&lt;/td&gt;
      &lt;td&gt;App Store search, Platform version information&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Plurals&lt;/td&gt;
      &lt;td&gt;Avoid plurals of words already included; “climbs” and “climb” count as duplicates&lt;/td&gt;
      &lt;td&gt;App Store search&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Avoid&lt;/td&gt;
      &lt;td&gt;Generic terms such as “app” or “game”, filler words such as “the” and “to”, special characters such as # or @ unless they’re part of your brand&lt;/td&gt;
      &lt;td&gt;App Store search&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Not allowed&lt;/td&gt;
      &lt;td&gt;Trademarked terms, celebrity names, competing app names, irrelevant or offensive terms&lt;/td&gt;
      &lt;td&gt;App Store search, product page&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Scope&lt;/td&gt;
      &lt;td&gt;One field per localization; part of the app version’s metadata&lt;/td&gt;
      &lt;td&gt;Platform version information&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Apple calls improper keyword use a common reason for App Store rejections, so the last two rows matter for review as well as for ranking.&lt;/p&gt;

&lt;h2 id=&quot;how-does-app-store-connect-count-the-100-characters&quot;&gt;How does App Store Connect count the 100 characters?&lt;/h2&gt;

&lt;p&gt;Everything in the field counts, letters, commas and spaces alike, which is why the no-spaces rule matters. Write the field the way people write lists, with a space after every comma, and ten terms cost you nine characters for nothing.&lt;/p&gt;

&lt;p&gt;Apple’s own pages disagree on the unit. The product page and search guides say 100 characters; the App Store Connect reference says 100 bytes. The counter in the App Store Connect form follows neither exactly: it counts the way JavaScript measures text length, in UTF-16 code units. For English, the other Latin-script languages, Cyrillic, Greek, and almost all Chinese, Japanese and Korean characters, that is one unit per character, so the distinction never comes up. It does come up in scripts that write vowels as combining signs. The Hindi word किराना (grocery) reads as three syllables but is six units. A Hindi keyword field can look two-thirds full and already be at the limit, so trust the counter in App Store Connect over a text editor’s.&lt;/p&gt;

&lt;h2 id=&quot;which-words-are-already-indexed-somewhere-else&quot;&gt;Which words are already indexed somewhere else?&lt;/h2&gt;

&lt;p&gt;Most wasted characters go on words like these, and Apple documents more of this than the folklore suggests.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Where the word appears&lt;/th&gt;
      &lt;th&gt;Searchable?&lt;/th&gt;
      &lt;th&gt;What Apple documents&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;App name&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;Named as text relevance (“title”) in the search guide&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Subtitle&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;Named as text relevance in the search guide&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Keyword field&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;Named as text relevance&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Company (developer) name&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;App Store Connect help: your app is searchable by “app name, app subtitle, keywords, and your company name”&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Primary and secondary category&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;“Your primary category and optional secondary category are indexed”&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Promotional text&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
      &lt;td&gt;Apple says it “doesn’t affect your app’s search ranking”&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Description&lt;/td&gt;
      &lt;td&gt;Not listed&lt;/td&gt;
      &lt;td&gt;Used for web search engine results after release; Apple asks you not to stuff it with keywords&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The company name line comes from the FAQ on Apple’s &lt;a href=&quot;https://developer.apple.com/help/app-store-connect/create-an-app-record/view-and-edit-app-information&quot;&gt;view and edit app information&lt;/a&gt; page, and the reference page adds that you shouldn’t duplicate those values in the keyword list. So if your seller name is “Northwind Labs”, “northwind” is already working for you without costing a character.&lt;/p&gt;

&lt;h2 id=&quot;a-worked-example-one-wasted-field-one-fixed&quot;&gt;A worked example: one wasted field, one fixed&lt;/h2&gt;

&lt;p&gt;A made-up app: &lt;strong&gt;Kestrel: Habit Tracker&lt;/strong&gt;, subtitle &lt;strong&gt;Daily goals and routines&lt;/strong&gt;, primary category Productivity. First draft of the English (U.S.) keywords, 94 characters:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;habit tracker, habits, daily goals, routine, routines, app, streaks, reminders, best habit app&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;What those characters buy:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Term&lt;/th&gt;
      &lt;th&gt;Problem&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;habit tracker&lt;/td&gt;
      &lt;td&gt;Both words are already in the name&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;habits&lt;/td&gt;
      &lt;td&gt;Plural of a word already in the name&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;daily goals&lt;/td&gt;
      &lt;td&gt;Both words are already in the subtitle&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;routine, routines&lt;/td&gt;
      &lt;td&gt;Already in the subtitle, once as a plural&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;app&lt;/td&gt;
      &lt;td&gt;Generic word Apple tells you to skip&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;best habit app&lt;/td&gt;
      &lt;td&gt;Repeats habit and app; “best” is the only new word&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;8 spaces after commas&lt;/td&gt;
      &lt;td&gt;8 characters that do nothing&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Out of 94 characters, the new words are streaks, reminders and best. The rewrite, 98 characters:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;streak,reminder,checklist,planner,journal,mood,water,sleep,focus,discipline,self care,todo,morning&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That is fourteen words, none of them in the name, subtitle or category, with no spaces after commas and one form of each word. It only works if the app really does track mood, water and sleep, because Apple’s rule against irrelevant terms applies to the rewrite too.&lt;/p&gt;

&lt;h2 id=&quot;what-does-apple-not-document-the-aso-folklore&quot;&gt;What does Apple not document? The ASO folklore&lt;/h2&gt;

&lt;p&gt;Plenty of keyword advice is reasonable and still unverified. These are the claims I see most, sorted by what Apple has written down.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Claim&lt;/th&gt;
      &lt;th&gt;Status&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Apple combines words from the name, subtitle and keywords into phrases, so single words beat phrases&lt;/td&gt;
      &lt;td&gt;Folklore. Widely reported from testing, not in Apple’s documentation. Apple’s own example keeps “Real Estate” as a phrase.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Plural matching works the same in every language, including irregular plurals&lt;/td&gt;
      &lt;td&gt;Folklore. Apple’s example is English (climbs, climb) and it says nothing about other languages.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Words in the app name count for more than words in the keyword field&lt;/td&gt;
      &lt;td&gt;Folklore. Apple lists the fields it matches, not their weights.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Some storefronts also search your keywords from other localizations&lt;/td&gt;
      &lt;td&gt;Folklore. Apple’s &lt;a href=&quot;https://developer.apple.com/help/app-store-connect/reference/app-information/app-store-localizations&quot;&gt;localization table&lt;/a&gt; lists additional supported languages per storefront (the U.S. includes Spanish (Mexico), among others) but says nothing about search.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;The description is indexed for App Store search&lt;/td&gt;
      &lt;td&gt;Not documented. Apple doesn’t name it as a search factor.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Competitor names in keywords work if nobody notices&lt;/td&gt;
      &lt;td&gt;Against the rules. Apple names competing app names as not allowed, and reviewers do notice.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Some of the folklore is probably right. Acting on it is still an experiment, so change one thing per version and watch the results.&lt;/p&gt;

&lt;h2 id=&quot;how-do-localizations-change-the-keyword-field&quot;&gt;How do localizations change the keyword field?&lt;/h2&gt;

&lt;p&gt;Each localization gets its own 100-character field. App Store Connect accepts metadata in 50 languages and locales now that Apple added &lt;a href=&quot;https://developer.apple.com/help/app-store-connect/release-notes/&quot;&gt;eleven more in March&lt;/a&gt;, including Bangla, Tamil and Urdu. Write each one for its language. People search with their own words, and a literal translation of the English field often lands on terms nobody types.&lt;/p&gt;

&lt;p&gt;The English variants are a good example. English (U.S.), English (U.K.), English (Canada) and English (Australia) are four localizations with four fields, and Apple’s table lists a different one as the default language in each of those storefronts. Spelling and vocabulary differ (color and colour, cell phone and mobile), so the U.S. field pasted into the other three still needs a pass for each.&lt;/p&gt;

&lt;h2 id=&quot;when-do-keyword-changes-go-live&quot;&gt;When do keyword changes go live?&lt;/h2&gt;

&lt;p&gt;The keyword field sits in the version section of App Store Connect, beside the description, so an edit ships with your next approved version. There’s no way to change keywords alone on a live version. So plan a small keyword change for each release; a hurried rewrite has to wait for review like any other version. Apple also notes that metadata updates can take up to 24 hours to appear in every storefront.&lt;/p&gt;

&lt;h2 id=&quot;where-appmeta-fits&quot;&gt;Where AppMeta fits&lt;/h2&gt;

&lt;p&gt;I check every keyword field I ship in &lt;a href=&quot;/apps/appmeta/&quot;&gt;AppMeta&lt;/a&gt;, the Mac client for App Store Connect I wrote about &lt;a href=&quot;/journal/native-mac-client-for-app-store-connect/&quot;&gt;in February&lt;/a&gt;. Its keyword checks run on the Mac against the metadata you’ve already entered, with no AI involved. They flag keyword words that already appear in the app name or subtitle, words repeated across keyword phrases, exact duplicate phrases, fields over 100 characters, and the same keywords copied across localizations of one language. That last check leans on the same storefront folklore as the table above, and the app’s Storefronts tab keeps Apple’s documented structure and the ASO heuristics in separate, labelled sections. It doesn’t detect plurals: “routine” and “routines” are two different words to it, so that one is still on you.&lt;/p&gt;

&lt;p&gt;All the localizations sit side by side, so you can see the gaps without opening each one. If you want suggestions, AppMeta can ask an AI provider you choose, with your own key, or Apple Intelligence on the Mac.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>Why Mac-native is the right architecture for App Store screenshots, and why it&apos;s so rare</title>
    <link href="https://lagerland-apps.github.io/journal/why-mac-native-for-app-store-screenshots/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/why-mac-native-for-app-store-screenshots/</id>
    <published>2026-05-13T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Every credible App Store screenshot tool on the market today is web-based. You drop your pre-release screenshots into someone else&apos;s browser, they get uploaded to someone else&apos;s servers and rendered there, and you download the result. That is a strange architecture for a product whose entire input is content under NDA. This post explains why Mac-native makes more sense, and why almost nobody builds it that way.</summary>
    <content type="html">&lt;p&gt;Looked at closely, the App Store screenshot tool category is a slightly absurd one.&lt;/p&gt;

&lt;p&gt;Open the top three Google results for “App Store screenshot generator” and try the workflow. You drop your pre-release screenshots, which by definition are still under embargo, into someone else’s web browser. The browser uploads them to someone else’s servers. The rendering, the device framing, and the AI translation pass all happen on infrastructure the vendor owns. Then you download the finished files and upload them, by hand, to App Store Connect.&lt;/p&gt;

&lt;p&gt;The workflow is perfectly normal. As an architecture it is odd for a tool whose entire input is content that hasn’t been announced yet. Once you notice that, you start to wonder why almost nobody builds the obvious alternative: a native Mac app that does the same job while every byte stays on your machine until you push it to Apple.&lt;/p&gt;

&lt;p&gt;This post tries to answer both halves of that: why Mac-native is the better architecture in this category, and why almost nobody builds it anyway.&lt;/p&gt;

&lt;h2 id=&quot;what-mac-native-actually-means-here&quot;&gt;What “Mac-native” actually means here&lt;/h2&gt;

&lt;p&gt;Here “Mac-native” means a few specific things, all of which come from running the workflow in a real macOS app and not in a browser:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Rendering happens on your machine.&lt;/strong&gt; When you place a screenshot inside a 3D iPhone frame, the geometry is rendered locally: your Mac’s GPU runs the Metal shaders that produce the final image. There is no upload, no remote render farm, and no waiting in someone else’s queue.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Files stay on disk.&lt;/strong&gt; Your raw screenshots, your localised text, and your project files all sit in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/Documents&lt;/code&gt; or wherever you put them. The screenshot tool reads and writes locally, and nothing leaves the machine unless you choose to push it.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;AI translation calls your provider directly.&lt;/strong&gt; When you ask the tool to translate “Track every workout in one tap” into Japanese, it makes the API call from your Mac to OpenAI / Anthropic / Google, using &lt;em&gt;your&lt;/em&gt; API key and billed to &lt;em&gt;your&lt;/em&gt; account. The screenshot tool’s vendor never sees the request.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;App Store Connect authentication uses Keychain.&lt;/strong&gt; When you push the finished screenshots to ASC, you authenticate via Apple’s official API. Your credentials live in Keychain, accessed by the app inside its sandbox, and not in a SaaS vendor’s database.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is what “native” buys you. Nostalgia for desktop software has nothing to do with it. It is one specific property of the architecture: &lt;em&gt;every byte of input, computation, and credential stays on your machine until you explicitly send it to Apple.&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;why-its-the-right-architecture-for-this-category&quot;&gt;Why it’s the right architecture for this category&lt;/h2&gt;

&lt;p&gt;Several reasons, roughly in ascending order of how often they come up:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NDA exposure.&lt;/strong&gt; This is the strongest case. If you’re shipping pre-release work for a client under a master services agreement, or pre-launch features for an embargoed announcement, “the screenshots passed through a third-party SaaS server” is almost certainly a contractual problem you don’t want. A vendor policy that says “we delete uploads after rendering” is still only a policy, and it sits on the wrong side of your trust boundary. With native rendering the question never comes up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deterministic re-renders.&lt;/strong&gt; When the rendering happens on your machine with deterministic GPU shaders, re-rendering tomorrow produces byte-for-byte identical output. Web-based renderers often re-render with slight differences across releases: different fonts loaded by the browser, different colour spaces, different anti-aliasing. If you may need to re-render the same project six months later for a minor update, that determinism matters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Speed.&lt;/strong&gt; Local Metal rendering at 4K, with full 3D device geometry and lighting, takes milliseconds per screenshot. The same render through a remote service typically takes 1 to 10 seconds per screenshot once you count upload, queueing, render, and download. For a project producing 234 screenshots (6 device sizes × 39 locales), that is a 5-second render against a 5-minute one. The local version also doesn’t depend on the vendor’s servers staying up tonight.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lower total cost.&lt;/strong&gt; When the rendering happens locally, the natural pricing model is a one-time purchase. A Mac app distributed via the App Store has no server bills and can live comfortably on a $20 to $50 one-time price. A SaaS web app runs render farms 24/7 and pretty much needs a subscription. That is why Mockly is $12.99 once and most competitors are $19 to $49 per month.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No account or login required.&lt;/strong&gt; There is simply nothing for an account to authenticate against. The app stores nothing server-side because there is no server, and you don’t need to recover your account when you change machines, because there isn’t one. Less friction and better privacy both follow from “the rendering happens here.”&lt;/p&gt;

&lt;h2 id=&quot;so-why-doesnt-everyone-build-it-this-way&quot;&gt;So why doesn’t everyone build it this way?&lt;/h2&gt;

&lt;p&gt;Because the business model decides the architecture, not the other way round.&lt;/p&gt;

&lt;p&gt;A SaaS subscription needs three things: a recurring infrastructure cost to justify the recurring price, lock-in to keep churn down, and costs that grow more slowly than revenue as users are added. The web architecture provides all three. The render farm is the recurring cost, the cloud project files you can’t take with you are the switching cost, and one more user costs about $0.10/month in compute.&lt;/p&gt;

&lt;p&gt;The Mac-native architecture provides none of them. The render is on the user’s machine, so there’s no recurring infrastructure cost to recoup. The project files are on the user’s disk, so there’s no lock-in; if anything it runs the other way, since users can mail their projects around. And the marginal cost per user is zero, so there’s no incremental revenue per active user to chase.&lt;/p&gt;

&lt;p&gt;So the Mac-native architecture is better for the user and worse for the vendor. That is the usual pattern for indie software, and it is why SaaS dominates the category even where SaaS is the wrong shape for the product.&lt;/p&gt;

&lt;p&gt;The SaaS competitors aren’t doing anything wrong. AppLaunchpad, Screenshots.pro, Screenshot Studio, and the others are reasonable products built under a reasonable business constraint. They optimise for a different goal, and that goal pushes them toward an architecture where your pre-release screenshots end up on someone else’s server.&lt;/p&gt;

&lt;h2 id=&quot;what-mockly-actually-does-differently&quot;&gt;What Mockly actually does differently&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/apps/mockly/&quot;&gt;Mockly&lt;/a&gt; is the Mac-native version. Specifically:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Metal rendering pipeline.&lt;/strong&gt; Real 3D device geometry, GPU-accelerated and deterministic, so a project re-rendered tomorrow comes out bit-for-bit identical. The same renderer handles every device class from iPhone 6.9” (1290×2868) down to Apple Watch (410×502) and up to visionOS (3840×2160).&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;AI translation against your own API key.&lt;/strong&gt; When you localise overlaid text into the 39 App Store locales, the translation calls go from your Mac directly to whichever model provider you configure: OpenAI, Anthropic, whatever. Mockly never sees the text. No Lagerland server is in the path, because there is no Lagerland server.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;App Store Connect upload via Keychain.&lt;/strong&gt; When you push the finished screenshots to ASC, you authenticate via Apple’s framework, and credentials live in Keychain. The upload goes straight to App Store Connect’s API, matched to each device and locale, with no manual browser uploads and no third party in between.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;One-time $12.99.&lt;/strong&gt; Family Sharing for up to six people. The architecture makes the low cost possible, and the low cost makes the one-time price possible.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The price follows from the architecture. Marketing didn’t set it.&lt;/p&gt;

&lt;h2 id=&quot;a-note-on-fastlane&quot;&gt;A note on Fastlane&lt;/h2&gt;

&lt;p&gt;For many indie developers, the honest answer to “why use a GUI tool at all” is that Fastlane takes real work to set up. Fastlane snapshot + frameit is the de facto open-source standard for automated App Store screenshot generation, and for teams with mature CI/CD it’s the right answer. The setup curve is steep, though: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Snapfile&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Snapshfile&lt;/code&gt;, UI tests in Xcode that drive the screenshot states, then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;frameit&lt;/code&gt; to overlay device frames, then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;deliver&lt;/code&gt; to upload. First-time setup takes several days.&lt;/p&gt;

&lt;p&gt;For solo developers and small teams, an hour of GUI-tool setup against a few days of Fastlane setup usually favours the GUI tool, especially if you ship new screenshots a few times a year. Mockly is a GUI alternative for those people; Fastlane is the right answer for teams that have already paid the setup cost.&lt;/p&gt;

&lt;h2 id=&quot;tldr&quot;&gt;TL;DR&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Every credible App Store screenshot tool is web-based: you drop screenshots into a browser, they render on the vendor’s server, and you download the result.&lt;/li&gt;
  &lt;li&gt;For a workflow whose input is pre-release content under NDA, that’s a strange architecture, with a third party in the data path for no functional benefit.&lt;/li&gt;
  &lt;li&gt;Mac-native means rendering happens on your machine via Metal, AI translation calls your own provider directly, and App Store Connect auth lives in Keychain. Every byte stays local until you push to Apple.&lt;/li&gt;
  &lt;li&gt;Web apps dominate because the SaaS subscription business model only works if rendering happens on the vendor’s infrastructure. User preference has little to do with it.&lt;/li&gt;
  &lt;li&gt;Mac-native is better for the user and worse for the vendor, which is why it’s rare.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/apps/mockly/&quot;&gt;Mockly&lt;/a&gt; is the Mac-native version: $12.99 once, with no subscription, no server, and no account.&lt;/li&gt;
&lt;/ul&gt;
</content>
  </entry>

  <entry>
    <title>What 14 days of Apple Health data is enough to reveal, and what isn&apos;t</title>
    <link href="https://lagerland-apps.github.io/journal/what-14-days-of-apple-health-can-reveal/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/what-14-days-of-apple-health-can-reveal/</id>
    <published>2026-05-13T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Apple Health is the largest passive health dataset most people will ever own, and almost nobody uses it for what it does well. This is a practical guide to which questions two weeks of data can answer, which ones need 60 days, and which ones it can&apos;t answer at all.</summary>
    <content type="html">&lt;p&gt;Most people I talk to have an Apple Watch and a Health app holding two or more years of data they have never opened or queried, let alone learned anything from.&lt;/p&gt;

&lt;p&gt;That’s not their fault. The Health app stores everything and interprets very little. It shows you yesterday’s resting heart rate. It does not tell you which of your habits keeps moving that number.&lt;/p&gt;

&lt;p&gt;Observa is meant to do that interpreting. Before getting into how it works, though, there is a practical question I get asked more than any other.&lt;/p&gt;

&lt;h2 id=&quot;how-much-data-do-you-actually-need-before-any-of-this-matters&quot;&gt;How much data do you actually need before any of this matters?&lt;/h2&gt;

&lt;p&gt;It depends on the question you’re asking, and the answer falls into three tiers.&lt;/p&gt;

&lt;h3 id=&quot;tier-1-two-weeks-for-single-variable-patterns&quot;&gt;Tier 1: Two weeks for single-variable patterns&lt;/h3&gt;

&lt;p&gt;Two weeks of consistent wear is the floor. After about 14 days you have enough nights of sleep, morning HRV readings, and workouts to start seeing single-variable correlations: &lt;em&gt;did this one habit consistently move this one metric?&lt;/em&gt; Insights at this stage look like this:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;Days you trained legs after 18:00, your deep sleep averaged 18% below baseline.&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;Nights with screen time within 30 minutes of sleep onset showed −24% deep-sleep share.&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;Coffee logged after 14:00 correlated with +4 bpm resting heart rate the following morning.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each one pairs a single cause with a single effect, backed by enough same-condition observations (n ≥ 10) and enough opposite-condition observations for a statistical comparison to mean something. Observa’s threshold is p ≤ 0.10. That is looser than academic research, which suits self-experimentation, where the cost of being wrong is “you try something else for two weeks.”&lt;/p&gt;

&lt;p&gt;What 14 days &lt;strong&gt;can’t&lt;/strong&gt; give you yet is anything multi-variable, seasonal, or dependent on training cycles. The data is real; the slice is too thin.&lt;/p&gt;

&lt;h3 id=&quot;tier-2-60-days-for-multi-variable-correlations&quot;&gt;Tier 2: 60 days for multi-variable correlations&lt;/h3&gt;

&lt;p&gt;Around the 60-day mark, two things become possible. Your personal baseline (the rolling mean and standard deviation for each metric: HRV (SDNN), RHR, sleep efficiency, deep-sleep share, REM share) settles enough that deviations from it mean something. And you have enough non-overlapping weekly samples to run multi-variable analysis.&lt;/p&gt;

&lt;p&gt;A multi-variable question is “did caffeine &lt;em&gt;combined with screen time on the same evening&lt;/em&gt; affect my HRV more than either alone?” where a single-variable one is “did caffeine affect my HRV?” Most of the useful self-knowledge sits in compound patterns like that. A late workout alone may cost you 4% deep sleep, while a late workout &lt;em&gt;plus&lt;/em&gt; a caffeinated afternoon may cost you 19%.&lt;/p&gt;

&lt;p&gt;Sixty days also happens to be around two menstrual cycles, two training mesocycles, and enough weekly variation to capture how your body changes through ordinary life. Observa’s Pro multi-variable engine uses this window.&lt;/p&gt;

&lt;h3 id=&quot;tier-3-90-to-365-days-for-trend-analysis&quot;&gt;Tier 3: 90 to 365 days for trend analysis&lt;/h3&gt;

&lt;p&gt;At this range &lt;em&gt;baseline drift&lt;/em&gt; becomes visible. Your resting heart rate is not a constant. It drops as you build aerobic fitness, drifts up during stressful periods, falls during taper weeks, and climbs through respiratory infections you don’t always notice. Tracking RHR week over week against last quarter shows you what “normal” looks like for your body. HRV works the same way: seasonal swings of 10 to 20% are common, and a common misreading is to take a winter dip as “I’m broken” when it only means “winter HRV runs lower.”&lt;/p&gt;

&lt;p&gt;Ninety days is enough to see one full mesocycle of training adaptation. Six months shows seasonal swings. A year is enough to detect anything meaningful about how your physiology changes.&lt;/p&gt;

&lt;h2 id=&quot;what-no-amount-of-apple-health-data-can-tell-you&quot;&gt;What no amount of Apple Health data can tell you&lt;/h2&gt;

&lt;p&gt;Causation. Consumer health apps routinely paper over this, and it matters a lot.&lt;/p&gt;

&lt;p&gt;Correlation analysis can tell you that on days you train legs after 18:00, your deep sleep drops 18%. It cannot tell you that the workout &lt;em&gt;caused&lt;/em&gt; the drop. Something you happen to do on the same days (caffeine timing, meeting load, stress, food choice, alcohol) may be the real cause. Statistical correlation alone never proves cause.&lt;/p&gt;

&lt;p&gt;So use correlation insights as &lt;strong&gt;hypotheses worth testing&lt;/strong&gt;, not as verdicts. If Observa flags “your sleep efficiency drops after late workouts” with high confidence, the useful response is to train earlier for two weeks and see whether your sleep efficiency improves. That is the only way to turn a correlation into something close to causal knowledge.&lt;/p&gt;

&lt;p&gt;That is also why Observa shows the n (sample size) and confidence on every Pro insight. You should be able to judge for yourself whether to act on a pattern with n=14 at 87% confidence vs one with n=8 at 60%.&lt;/p&gt;

&lt;h2 id=&quot;why-personal-baselines-matter-more-than-recovery-scores&quot;&gt;Why personal baselines matter more than recovery scores&lt;/h2&gt;

&lt;p&gt;Many consumer health apps compute a single daily score: WHOOP-style 0 to 100 recovery, an Apple-Watch-style “Mind &amp;amp; Body Hello”, Athlytic’s recovery percentage, a Bevel-style biological age. These work as summaries you can read at a glance. They are also opaque, and you can see very little of &lt;em&gt;what’s moving them&lt;/em&gt; from day to day.&lt;/p&gt;

&lt;p&gt;Observa never shows a single score. It always shows the underlying metric measured against your own 60-day baseline. “Your HRV (SDNN) is 18% below your personal 60-day baseline” tells you something specific. “Your recovery is 58/100” tells you something &lt;em&gt;averaged&lt;/em&gt;, and when you ask “why?”, the score has no answer.&lt;/p&gt;

&lt;p&gt;For the same reason, comparing your numbers to someone else’s is almost always a waste of time. Absolute HRV varies enormously by age, sex, fitness, measurement timing, and which wrist your watch is on. The comparison that tells you something is &lt;em&gt;you, today, vs. you, on average, over the last two months.&lt;/em&gt; Everything else is noise.&lt;/p&gt;

&lt;h2 id=&quot;a-note-on-apple-watch-hrv-specifically&quot;&gt;A note on Apple Watch HRV specifically&lt;/h2&gt;

&lt;p&gt;Apple Watch measures HRV as SDNN (the standard deviation of successive heartbeat intervals), at variable times during the day and overnight and mostly when you’re still. Most sports-science tools use RMSSD instead. The absolute numbers are not directly comparable to chest-strap measurements or to numbers from a different watch. What you can compare is &lt;em&gt;your watch’s reading of you over time&lt;/em&gt;, so track that SDNN reading against a 60-day mean and don’t hold your raw number up against a friend’s.&lt;/p&gt;

&lt;p&gt;Apple Watch also captures ECG sinus-rhythm data on Series 4 and later, which adds real recovery signal when read in context. Sleep stage data (deep, REM, core, awake) comes from a combination of motion and heart rate variability. It is accurate enough for tracking trends and not accurate enough for clinical sleep staging.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/apps/observa/&quot;&gt;Observa&lt;/a&gt; reads all of this from your Health app, computes a 60-day rolling baseline for every metric, and shows single-variable patterns on the free tier and multi-variable patterns on Pro. Everything runs on your device, with no upload, no account, and no servers. The aim is to make use of what Apple Health has been collecting for years.&lt;/p&gt;

&lt;h2 id=&quot;tldr&quot;&gt;TL;DR&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;14 days&lt;/strong&gt; is enough for single-variable patterns: late workouts and deep sleep, caffeine and RHR, screen time and sleep latency.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;60 days&lt;/strong&gt; is the minimum for multi-variable correlations (training load × caffeine × sleep) and for a stable personal baseline.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;90 to 365 days&lt;/strong&gt; is needed for trend analysis: seasonal HRV swings, RHR drift, training adaptation curves.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Correlation is not causation.&lt;/strong&gt; Treat every insight as a hypothesis worth testing for two weeks.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Compare yourself to your baseline, not to other people.&lt;/strong&gt; Absolute HRV/RHR numbers vary enormously between bodies.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The data has been piling up in your Health app since you got the watch. What it lacked was something that could read it.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>How to ship a localised App Store screenshot set in 39 languages without losing your weekend</title>
    <link href="https://lagerland-apps.github.io/journal/shipping-app-store-screenshots-in-39-languages/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/shipping-app-store-screenshots-in-39-languages/</id>
    <published>2026-05-13T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">App Store Connect accepts screenshots in 39 locales. Most indie apps ship in one, because the manual workflow takes 10 to 30 hours per release, and any change to a single screenshot means redoing the localisation pass. This post walks through a reproducible workflow that takes 90 minutes for the first release and 15 minutes for each subsequent one.</summary>
    <content type="html">&lt;p&gt;App Store Connect accepts screenshots in 39 locales. Almost every indie app ships in one, usually en-US, sometimes also Japanese or German. The gap between what’s possible and what gets done comes down to the manual workflow, which takes long enough to consume an entire weekend on the first attempt and an evening on every subsequent release.&lt;/p&gt;

&lt;p&gt;This post is the workflow I’d recommend to any indie developer going from one locale to 39, with the upfront cost cut to about 90 minutes and the per-release cost to about 15 minutes. The manual workflow is expensive because most screenshot pipelines bake text into images, which makes the localisation pass O(n) in human hours. If you keep text as an editable overlay layer, the localisation pass becomes O(1) in human hours and O(n) in machine compute, which is a much better trade.&lt;/p&gt;

&lt;h2 id=&quot;why-the-manual-workflow-is-so-slow&quot;&gt;Why the manual workflow is so slow&lt;/h2&gt;

&lt;p&gt;If you’re doing this manually today, your time probably looks something like this for a release with 6 screenshots per device class across 4 device classes (iPhone 6.9”, 6.7”, iPad 13”, Mac):&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Design pass:&lt;/strong&gt; 1 to 2 hours to build the 6 base screenshots in Figma or your design tool of choice. This is the actual creative work, and the time is well spent.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Localisation prep:&lt;/strong&gt; 1 to 3 hours getting feature copy translated. Either you wait for human translators (multi-day roundtrip), or you batch-paste into ChatGPT/Claude/DeepL and edit the worst output, or you’ve already invested in a translation memory tool.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Layout pass:&lt;/strong&gt; This is the slow part. 6 screenshots × 39 locales = 234 unique layouts. If each takes 1 minute to render (in a fast workflow with text-as-layer) you get 4 hours. If each takes 5 minutes (baked-text workflow with per-locale edits and re-renders) you get 20 hours.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;App Store Connect upload pass:&lt;/strong&gt; The web UI is a per-locale, per-device-class form. You select a locale tab, drag in 6 files for iPhone 6.9”, wait for upload, switch to iPhone 6.7”, drag in 6 more, repeat for iPad and Mac, switch to the next locale, and do it all again. Plan for 2 to 4 hours of attention.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s 8 to 30 hours total per release, depending entirely on whether your screenshot pipeline keeps text as a layer or bakes it in. Every subsequent release that changes a single source screenshot or a single string repeats most of the pain.&lt;/p&gt;

&lt;p&gt;That is why almost every indie app ships in one or two locales. Apple is right to want localised screenshots, and its requirements are reasonable; the consumer tooling makes the workflow so expensive that nobody actually does it.&lt;/p&gt;

&lt;h2 id=&quot;the-architecture-that-makes-39-locales-cheap&quot;&gt;The architecture that makes 39 locales cheap&lt;/h2&gt;

&lt;p&gt;Keep your text as a separate, editable overlay layer, and never bake it into the screenshot image. Once you adopt that constraint, everything downstream becomes mechanical.&lt;/p&gt;

&lt;p&gt;What that means in each tool:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;In Figma:&lt;/strong&gt; the base screenshot is one component (a flat image layer). The feature copy is a separate Text node on top of it. To localise, you duplicate the frame and edit the Text node’s content; the base image stays referenced from the same source.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;In Sketch:&lt;/strong&gt; same pattern. Flat screenshot layer, text node on top. Localise the text node.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;In Mockly:&lt;/strong&gt; the architecture is built in. Every screenshot is a project with the raw capture as one layer, the device frame as a 3D rendered layer, and overlaid text as separate editable text elements. AI translation operates on the text elements only; the captured screen content is byte-identical across all 39 locales.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once text is a layer, you can:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Run AI translation against all 39 locales in seconds rather than days.&lt;/li&gt;
  &lt;li&gt;Render each (locale × device size) combination from the same source in milliseconds rather than minutes.&lt;/li&gt;
  &lt;li&gt;Re-render the entire 234-screenshot bundle bit-for-bit identically when you change a single string.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is how a release gets down to 15 minutes: the expensive parts (rendering, layout, upload) become mechanical compute instead of human labour.&lt;/p&gt;

&lt;h2 id=&quot;the-90-minute-first-release-workflow&quot;&gt;The 90-minute first-release workflow&lt;/h2&gt;

&lt;p&gt;Assuming you’ve done the initial design pass already (the 1 to 2 hours of actual creative work) and you have base screenshots with text-as-layer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1 (15 min):&lt;/strong&gt; Set up locale list. App Store Connect supports 39 locales; you don’t have to ship all of them. Pick the 5 to 10 that match your largest addressable markets. Most indie apps see meaningful conversion lift from English + Japanese + Simplified Chinese + German + Spanish + Korean. Expand from there as data justifies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2 (10 min):&lt;/strong&gt; Configure your AI translation provider. OpenAI’s GPT-4, Anthropic’s Claude, and DeepL are the three I’d recommend in 2026. All produce App-Store-acceptable output with English/Japanese/Chinese/German source-target pairs. For RTL languages (Arabic, Hebrew), spot-check Claude or use a native speaker review pass for the first release.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3 (5 min):&lt;/strong&gt; Run translation. If you’re using Mockly: paste your base text strings, select target locales, click “Translate.” Output goes straight into the layered project per locale. If you’re using a manual workflow: paste each base string into the AI tool, get the 39-locale output, paste back into your design tool one locale at a time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4 (20 min):&lt;/strong&gt; Render every (device × locale) combination. Mockly handles this with one button and ~50 milliseconds per render. A manual Figma workflow can be scripted with the Figma API but requires upfront setup; without scripting, this is the part where the 90-minute workflow stretches.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5 (10 min):&lt;/strong&gt; Spot-check the RTL languages and any high-stakes locale (typically Japanese, where the character density differs from English and overflow is common). Adjust text overlay sizes if anything looks off.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6 (5 min):&lt;/strong&gt; Upload via App Store Connect API. Mockly’s direct upload pipeline handles this; Fastlane &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;deliver&lt;/code&gt; is the open-source alternative if you’ve invested in Fastlane setup. Either way, it takes ~3 minutes of compute for a full 234-screenshot bundle.&lt;/p&gt;

&lt;p&gt;Total: about 65 minutes if everything goes smoothly, 90 if you hit one or two spot-check issues. After this, every subsequent release is 15 minutes because the architecture is in place.&lt;/p&gt;

&lt;h2 id=&quot;what-goes-wrong-and-how-to-avoid-it&quot;&gt;What goes wrong, and how to avoid it&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;RTL languages need explicit handling.&lt;/strong&gt; Arabic and Hebrew layouts flip: left-aligned overlay text should become right-aligned, and visual reading order may need to mirror. Tools that use Apple’s standard text-direction APIs handle this automatically; tools that don’t will produce broken-looking Arabic output. Always native-speaker-review the first Arabic release.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Japanese and Chinese character density is different.&lt;/strong&gt; A 7-word English headline fits in a header band; the same headline in Japanese may be 3 characters wide, and in German may be 12 words long and overflow. Build the text overlay with auto-resize or explicit length budgets per locale instead of fixed pixel widths.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sometimes the AI translation gets a domain term wrong.&lt;/strong&gt; “Workout” in fitness context translates differently from “workout” in general fitness. Use a glossary or instruct the AI translation tool with brand-specific term mappings. For a fitness app: provide a 5-term glossary mapping reps / sets / RPE / etc. to native equivalents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don’t translate proper nouns.&lt;/strong&gt; Your app name stays “Strava” in every locale. Some translation tools will helpfully render “Strava” into the target script (it shouldn’t); confirm proper-noun handling on first run.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;App Store Connect rate limits matter for bulk upload.&lt;/strong&gt; The Connect API has burst limits. Tools that respect them (Mockly’s pipeline, Fastlane deliver with proper config) upload cleanly; tools that hammer the API can get temporary backoff.&lt;/p&gt;

&lt;h2 id=&quot;what-the-actual-tools-cost&quot;&gt;What the actual tools cost&lt;/h2&gt;

&lt;p&gt;The economics for 2026 indie pipelines:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Figma + manual translation + manual upload:&lt;/strong&gt; Free (within Figma free plan). Time cost is the 10 to 30 hours described above. For an app shipping 3 releases per year that’s 30 to 90 hours per year, or half a developer-week.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Figma + AI translation (BYO API) + manual upload:&lt;/strong&gt; ~$2 to $5 of API calls per release. Time cost drops to 4 to 10 hours.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Subscription SaaS (Screenshots.pro / AppLaunchpad Pro / Screenshot Studio):&lt;/strong&gt; $19 to $49 per month, or $228 to $588 per year. Time cost drops to 1 to 3 hours per release.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/apps/mockly/&quot;&gt;Mockly&lt;/a&gt; (one-time $12.99):&lt;/strong&gt; Time cost drops to 90 min first release, 15 min subsequent releases. AI translation against your own API key (~$0.50 to $2 per release at 2026 API prices).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The price of the tool is small next to the cost of the time. What matters most is which workflow architecture you adopt.&lt;/p&gt;

&lt;h2 id=&quot;tldr&quot;&gt;TL;DR&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;39-locale localisation manually costs 10 to 30 hours per release&lt;/strong&gt; and most indie apps skip it entirely for this reason.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The fix is architectural:&lt;/strong&gt; keep overlaid text as a separate editable layer in your design tool, and never bake it into the screenshot image.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Once text-as-layer is in place,&lt;/strong&gt; AI translation runs in seconds, rendering in milliseconds, and the App Store Connect API bulk-uploads in minutes.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;First release: 90 minutes. Subsequent releases: 15 minutes.&lt;/strong&gt; The first hour of architecture work pays back many hours over each year of releases.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Watch for RTL handling (Arabic/Hebrew),&lt;/strong&gt; character density differences (Japanese/Chinese/German), proper-noun preservation, and App Store Connect API rate limits.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Related reading:&lt;/strong&gt; &lt;a href=&quot;/journal/why-mac-native-for-app-store-screenshots/&quot;&gt;Why Mac-native is the right architecture for App Store screenshots&lt;/a&gt; explains why local rendering matters for the architecture above, and &lt;a href=&quot;/journal/app-store-screenshot-review-guidelines-explained/&quot;&gt;What every App Store Review Guidelines screenshot rule actually means&lt;/a&gt; covers the compliance side of the same pipeline.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whether you can ship 39 locales comes down to whether your text layer is editable. Get that right and the rest is mechanical.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>How Plan Mode builds a wedding (or trip, or pregnancy) checklist</title>
    <link href="https://lagerland-apps.github.io/journal/how-plan-mode-builds-a-checklist/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/how-plan-mode-builds-a-checklist/</id>
    <published>2026-05-13T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Most countdown apps stop at the number of days. Soon.&apos;s Plan Mode also builds a checklist for the event type and schedules each task backward from the date. This is how the template engine works, why it counts down to the date (T-minus) and not up from today (T-plus), and what we left out on purpose.</summary>
    <content type="html">&lt;p&gt;Most countdown apps stop at days because days are easy. Subtract one date from another and you get a number. You can render that number large, pin a photo behind it, and ship.&lt;/p&gt;

&lt;p&gt;Soon. does that too. Plan Mode is the layer after the number, and it is what makes Soon. a planner: a checklist of what to do between now and the date, matched to the event type, scheduled backward from the date, and shown one task at a time.&lt;/p&gt;

&lt;p&gt;This post is the design note for that engine: what it does, what it leaves out on purpose, and why.&lt;/p&gt;

&lt;h2 id=&quot;templates-instead-of-generation&quot;&gt;Templates instead of generation&lt;/h2&gt;

&lt;p&gt;Every Plan Mode checklist is a template. There are templates for Trip, Wedding, Birthday, Pregnancy, Graduation, Move, Concert, and Anniversary, plus a blank Custom type for anything else.&lt;/p&gt;

&lt;p&gt;The templates are written once, shipped in the app binary, and the same for every user. We chose that on purpose, and the choice needs some defending.&lt;/p&gt;

&lt;p&gt;The alternative is generation: when an event is created, send the event type and date to a server (or an on-device LLM) and get back a personalised checklist. We considered it and decided against it for four reasons.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Generation requires data leaving the device.&lt;/strong&gt; Even with a local model, the design pressure is to give the model more context so the output gets better, and the more context you collect, the weaker the privacy guarantee gets. Templates that ship in the binary cannot leak event details.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Generated checklists are inconsistent.&lt;/strong&gt; A wedding template written once is the same checklist for every user, so two friends comparing notes start from the same baseline. A generated checklist might include the rehearsal dinner one time and skip it the next, or add a task that doesn’t exist. We optimise for stability.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Writing templates by hand is slow, and that helps.&lt;/strong&gt; Writing a good wedding template forces a person to ask whether a task comes seventh or first. An LLM doesn’t ask that, and the slow part of writing is where the order gets fixed.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Templates can be audited.&lt;/strong&gt; A user can read the entire wedding template before installing the app. Nothing is hidden behind it.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So every Plan Mode template is a list, written by a person, and the same for everyone.&lt;/p&gt;

&lt;h2 id=&quot;t-minus-not-t-plus&quot;&gt;T-minus, not T-plus&lt;/h2&gt;

&lt;p&gt;The second design decision is that tasks are anchored to T-minus offsets from the event date, not to calendar dates.&lt;/p&gt;

&lt;p&gt;A Plan Mode template entry looks like this internally:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;Trip · T-14 · “Buy travel adapter, check passport expiry”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When you create a trip event with a date of, say, August 12th, Plan Mode walks every entry in the template and computes its calendar day from the event date: T-14 becomes July 29th, T-3 becomes August 9th, T-1 becomes August 11th. Every task lands on its own day.&lt;/p&gt;

&lt;p&gt;Offsets let the template work for any event date in any year. A trip in seven months and a trip in three weeks use the same template; only the dates the offsets land on change. It is also how people think about prep. You tell your photographer &lt;em&gt;“two weeks before the wedding,”&lt;/em&gt; not &lt;em&gt;“July 29th.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The widgets benefit too. The Lock Screen, StandBy, and Home Screen widgets all show days to go, so T-minus is already the app’s native unit, and the planning layer uses the same one.&lt;/p&gt;

&lt;h2 id=&quot;one-notification-per-task&quot;&gt;One notification per task&lt;/h2&gt;

&lt;p&gt;If you opt into event notifications (Premium), Soon. sends one notification per Plan Mode task, on the day that task is due. That means no daily notification and no single notification for the whole event.&lt;/p&gt;

&lt;p&gt;For a trip 30 days out, the notifications across the month look like this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;T-30  Book flights
T-21  Reserve accommodation
T-14  Buy travel adapter, check passport expiry
T-10  Destination weather appears on widget
T-7   Refill any prescriptions
T-3   Pack (with weather-aware suggestions)
T-1   Charge devices, check-in opens
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That’s seven notifications over a month, each one something you can act on the day it arrives. A generic countdown app would fire “30 days until your trip!” every morning for thirty mornings, which tells you nothing new.&lt;/p&gt;

&lt;p&gt;The free tier of Soon. doesn’t notify at all. Plan Mode shows on the event card and the widget; notifications are a Premium addition for people who want to be prompted, where the free tier only shows the list.&lt;/p&gt;

&lt;h2 id=&quot;what-plan-mode-leaves-out&quot;&gt;What Plan Mode leaves out&lt;/h2&gt;

&lt;p&gt;It doesn’t restructure your checklist. If you hide a task, it stays hidden, and Soon. won’t re-add it next week. If you move a task from T-14 to T-21, that is where it stays.&lt;/p&gt;

&lt;p&gt;It doesn’t share. Soon. is on-device only. Plan Mode checklists don’t sync between users, so two people planning the same wedding each install Soon. and create the event separately.&lt;/p&gt;

&lt;p&gt;It doesn’t optimise. No algorithm watches which tasks you complete and reweights the template. The template you start with is the template you get, and any personalisation comes from your own edits.&lt;/p&gt;

&lt;p&gt;It doesn’t track you. Soon. has no analytics SDK, no event-completion telemetry, and no feedback loop reporting whether a notification worked. We don’t know which tasks users check off, ignore, or reschedule, and we don’t want to.&lt;/p&gt;

&lt;p&gt;We didn’t forget these features. We considered and prototyped each of them, then removed them.&lt;/p&gt;

&lt;h2 id=&quot;the-templates-in-full&quot;&gt;The templates, in full&lt;/h2&gt;

&lt;p&gt;Every Plan Mode template is listed on the &lt;a href=&quot;/apps/soon/#templates&quot;&gt;Soon. landing page&lt;/a&gt;: Trip (30-day), Wedding (90-day), Pregnancy (40-week), Birthday (14-day), Graduation (21-day), Move (45-day). Each is the exact task list you get when you create an event of that type, with the exact T-minus offsets that schedule the tasks.&lt;/p&gt;

&lt;p&gt;The Pregnancy template counts in weeks (Week 28, Week 32, Week 35) because that’s how pregnancy is discussed, by clinicians and by everyone else. The Wedding template starts at T-90 because the slow prep (vendor confirmation, save-the-dates, dress fittings) begins earlier than for other events. The Trip template starts at T-30 because in practice most trips aren’t planned further ahead than that.&lt;/p&gt;

&lt;p&gt;Those offsets are the author’s judgement, with no usage data behind them. If they’re wrong for your event, edit them.&lt;/p&gt;

&lt;h2 id=&quot;beyond-soon&quot;&gt;Beyond Soon.&lt;/h2&gt;

&lt;p&gt;Most apps that try to do planning end up either (a) too generic to be useful, or (b) so configurable that they need setup work nobody wants to do. Templates per event type sit between the two: they ship with sensible defaults, can be edited, and don’t try to learn anything about you.&lt;/p&gt;

&lt;p&gt;For a countdown app the engineering is light. A template is a list, and a T-minus offset is subtraction. The hard part is writing the lists well, which is a writing problem more than a technical one.&lt;/p&gt;

&lt;p&gt;If you build planning features into a vertical app (workout, cooking, study, project), the same shape works: ship templates, anchor them to a meaningful zero such as the date, the deadline or the milestone, schedule backward, fire one prompt per task on its day, and stop there. Leave out the AI, the tracking and the auto-tuning, and ship the list.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;a href=&quot;https://apps.apple.com/app/id6757280643&quot;&gt;Soon. is available on the App Store.&lt;/a&gt; It is free with 5 events, with no time limit; Premium unlocks weather intelligence, daily notes, recurring events, and one-task-per-day Plan Mode notifications. The full Plan Mode template gallery is on the &lt;a href=&quot;/apps/soon/#templates&quot;&gt;Soon. landing page&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>How Chessful turns a Stockfish evaluation into adaptive training</title>
    <link href="https://lagerland-apps.github.io/journal/how-chessful-builds-adaptive-training/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/how-chessful-builds-adaptive-training/</id>
    <published>2026-05-13T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Most chess apps that claim &apos;adaptive training&apos; adapt to a generic difficulty curve over a fixed puzzle pool, not to your games. Chessful adapts to the specific mistake patterns in your real losses. This post is the design note for that engine: how raw centipawn output becomes a motif classification, how motifs become skill-bucket flags, and how those flags become a spaced-repetition training queue. Every step is described, with nothing held back as a secret.</summary>
    <content type="html">&lt;p&gt;When a chess app says “adaptive training,” it usually means one of two things: “we have a difficulty slider,” or “we have a recommendation algorithm over a fixed puzzle library.” Chessful does neither.&lt;/p&gt;

&lt;p&gt;Chessful’s adaptive training adapts to &lt;strong&gt;your specific games&lt;/strong&gt;. The session you get tomorrow is generated from the mistakes in the games you played yesterday. If you spent last weekend hanging back-rank defenders, this week’s queue drills back-rank defenders. If you finally stop doing that and start misjudging king-and-pawn endgames, the queue moves on to opposition technique.&lt;/p&gt;

&lt;p&gt;This is the design note for how that works, organised around the five stages between “you played a game” and “tomorrow’s training session is ready,” in order. None of it is new computer science. It combines well-understood techniques (engine analysis, rule-based classification, spaced repetition), and most of the work went into the judgement calls that decide whether the feature works.&lt;/p&gt;

&lt;h2 id=&quot;stage-1-stockfish-on-device&quot;&gt;Stage 1: Stockfish on-device&lt;/h2&gt;

&lt;p&gt;At the end of every Chessful game, the position goes to a local Stockfish process on the same device. There is no cloud call. The engine’s depth is tuned to the device (deeper on Macs and recent iPads, shallower on older iPhones), and it produces a centipawn evaluation per move.&lt;/p&gt;

&lt;p&gt;This part of the pipeline looks most like Chess.com, Lichess, and every other chess analyser. It’s a commodity. In Chessful, though, the centipawn output is the &lt;strong&gt;input&lt;/strong&gt; to the next stage and not the thing the user gets. Other apps show a centipawn graph and call it “analysis,” and Chessful is structured specifically to avoid that.&lt;/p&gt;

&lt;p&gt;On engine depth: it’s tempting to run the engine deeper to find more mistakes, and we decided against it. A 13-ply analysis finds the mistakes that matter for a club player rated 800 to 1800; a 25-ply analysis turns up lines that even good players can’t read. We want patterns the user can act on, and a show of engine strength doesn’t help with that.&lt;/p&gt;

&lt;h2 id=&quot;stage-2-motif-classification&quot;&gt;Stage 2: Motif classification&lt;/h2&gt;

&lt;p&gt;This is where Chessful departs from other chess analysers. The centipawn evaluation goes through a &lt;strong&gt;layered motif classifier&lt;/strong&gt;: hand-curated rule-based detectors plus a small on-device language model. The classifier takes a position where the user lost a significant amount of centipawn value and labels it with one of about thirty motif categories.&lt;/p&gt;

&lt;p&gt;Some of the categories (the list isn’t complete):&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Tactical motifs:&lt;/strong&gt; hung piece, missed fork, missed pin, missed skewer, missed discovered attack, missed double attack, missed deflection, missed overload, back-rank threat, smothered mate possibility.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Defensive motifs:&lt;/strong&gt; defender-removal blindness (the piece you captured with was the only defender of another of your pieces), king-safety underestimate, prophylactic skip, weakening pawn push without compensation.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Positional motifs:&lt;/strong&gt; wrong piece traded (good bishop for a bad knight), wrong side castled, weak square allowed, wrong pawn break, time-on-the-clock-on-the-wrong-move.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Opening motifs:&lt;/strong&gt; repertoire drift (you deviated from your usual opening setup), book-move missed, transposition into a known-bad line.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Endgame motifs:&lt;/strong&gt; opposition direction error, king-too-late, wrong rook activation, drawn-but-played-on, wrong-color bishop endgame mistake.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each significant mistake gets exactly one label, chosen by the strictest matching detector. The rules are ordered and the first match wins, so one position can’t be classified as five different things and dilute the training signal.&lt;/p&gt;

&lt;p&gt;We use hand-curated rules instead of a learned classifier for two reasons. First, &lt;strong&gt;rules are auditable&lt;/strong&gt;: if the trainer drills the wrong pattern, we can read the rule and fix it. A learned classifier for chess motifs would be opaque, and it would drift between app updates as the model gets retrained, so the user’s “improvement” might just be the algorithm changing what it counts as a mistake. Second, the &lt;strong&gt;chess motif catalogue is small enough to handle by hand&lt;/strong&gt;. Roughly thirty mistake categories matter for club players. Encoding them as rules over the engine’s output is real engineering work, but the amount is bounded, and a trained classifier wouldn’t beat rules on a problem this constrained.&lt;/p&gt;

&lt;p&gt;The small on-device language model works on the explanation layer. It turns the motif label and the engine evaluation into the one or two sentences the user reads, and it doesn’t do any classification.&lt;/p&gt;

&lt;h2 id=&quot;stage-3-skill-bucket-flagging&quot;&gt;Stage 3: Skill-bucket flagging&lt;/h2&gt;

&lt;p&gt;Each of the thirty or so motif categories maps to one of five &lt;strong&gt;skill dimensions&lt;/strong&gt;: tactics, defense, positional play, openings, and endgames. When a mistake is classified, its skill bucket gets a flag. The flag holds the motif label, the position, the move you played, the move you should have played, and a plain-language explanation.&lt;/p&gt;

&lt;p&gt;You can see the buckets in the app: how many tactical motifs were flagged this week, which ones they were (mostly missed forks? mostly back-rank threats?), and how the count compares with two weeks ago. Premium adds long-term trend graphs (90 / 180 / 365 days), so you can see whether, say, your defense flag count is really going down over a quarter or has levelled off.&lt;/p&gt;

&lt;p&gt;Showing this matters because &lt;strong&gt;adaptive training only works if the user trusts the algorithm&lt;/strong&gt;. If the next session drills “back-rank threats” and the user has no idea why, they lose interest. If they can see that the algorithm is drilling back-rank threats because they made the same mistake in three of their last five losses, they do the session, and the session works.&lt;/p&gt;

&lt;h2 id=&quot;stage-4-spaced-repetition-queue-generation&quot;&gt;Stage 4: Spaced-repetition queue generation&lt;/h2&gt;

&lt;p&gt;Each training session pulls a set of positions from the flagged buckets, scheduled with &lt;strong&gt;spaced repetition&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Spaced repetition is the standard memory technique for pattern recognition. Anki popularised it for languages; SuperMemo formalised the underlying schedule decades ago. The mechanics are simple: positions you’ve seen recently come back sooner, positions you’ve solved correctly several times in a row drop out of rotation, and positions you got wrong recently come back fast.&lt;/p&gt;

&lt;p&gt;It suits chess because chess pattern recognition is more a &lt;strong&gt;memory task than a calculation task&lt;/strong&gt;. A 1600 player beats a 1400 player on the same tactical position mostly because the 1600 has seen the pattern often enough to recognise it within two seconds. Making the 1400 player see the pattern again and again at growing intervals is the right way to teach it. It’s dull, and it works.&lt;/p&gt;

&lt;p&gt;Chessful uses a Leitner-style schedule (boxes 1 through 5, with intervals of roughly 1 day, 3 days, 7 days, 14 days, and 30 days). A newly flagged motif starts in box 1. A correct solve moves it up a box; a wrong one sends it back to box 1. After two correct solves in box 5 the motif leaves rotation, though it can come back if a new game flags the same motif again.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Free tier: three sessions per week.&lt;/strong&gt; Three sessions cover the highest-priority bucket flags, but you have to choose. Premium gives unlimited sessions. Premium makes sense for players who are serious about improving; the free tier is real training for casual players.&lt;/p&gt;

&lt;h2 id=&quot;stage-5-skill-graphs-and-the-feedback-loop&quot;&gt;Stage 5: Skill graphs and the feedback loop&lt;/h2&gt;

&lt;p&gt;After each session the graphs for each skill dimension update. The Free tier shows the current week and the previous week. Premium adds 90 / 180 / 365-day views.&lt;/p&gt;

&lt;p&gt;The graphs exist for the &lt;strong&gt;feedback loop&lt;/strong&gt;. If you’re three weeks into drilling defense motifs and the defense bucket count is still going up, the drills aren’t working and you need to try something else. Maybe the motif you keep missing isn’t a defense problem at all but a calculation problem that’s been misclassified. Maybe you’re tired and rushing the drills. Maybe you’re playing in time trouble, the motif is fine, and time management is what’s holding you back. The graphs let you answer those questions.&lt;/p&gt;

&lt;p&gt;This part of the engine takes longest to pay off. Most users ignore the trend graphs until they’ve used the app for a month or two. After that, the graphs are what keep them training, because they can see the curve move, or see that it doesn’t, and react.&lt;/p&gt;

&lt;h2 id=&quot;what-adaptive-training-in-chessful-doesnt-do&quot;&gt;What adaptive training in Chessful doesn’t do&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;It doesn’t replace studying.&lt;/strong&gt; Drilling motifs from your own games closes specific gaps, but you still need to work through an endgame book or a structured course on the Sicilian Dragon. Many improving players use Chessful alongside Magnus Trainer, Chessable, or printed books. Structured study and adaptive drilling on your real losses add up.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;It doesn’t replace playing.&lt;/strong&gt; The engine needs your games to work with. Chessful has 40 AI opponents to play against, but the training queue depends on having games to draw from. Three games is the minimum for useful training; at ten games the queue gets really specific.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;It doesn’t replace live human play.&lt;/strong&gt; Chessful has no live matchmaking and we aren’t planning to add it. Our view is that the improvement that happens between games has too few tools, while Chess.com and Lichess cover live play well. The two complement each other.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;It isn’t personalised by an opaque AI.&lt;/strong&gt; The motif categories and skill buckets are explicit, and the spaced-repetition schedule is well known. You can read what the trainer is doing and argue with it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;why-publish-this&quot;&gt;Why publish this&lt;/h2&gt;

&lt;p&gt;Most chess apps with adaptive training don’t say what the algorithm does. Usually it isn’t a trade secret. “Adaptive training” often just means “we picked a difficulty curve,” and saying so would deflate the marketing. By publishing ours we’re saying there is a real mechanism here, built on established techniques (Stockfish + rules + Leitner-style spaced repetition), and you can check over a month of your own games whether it works.&lt;/p&gt;

&lt;p&gt;It’s also because &lt;strong&gt;we publish our algorithms by default at Lagerland&lt;/strong&gt;. Plateau detection in &lt;a href=&quot;/apps/gymlogger-x/&quot;&gt;GymLogger X&lt;/a&gt; is documented the same way. The pattern recognition rules in &lt;a href=&quot;/apps/observa/&quot;&gt;Observa&lt;/a&gt; are published. The Plan Mode template engine in &lt;a href=&quot;/apps/soon/&quot;&gt;Soon.&lt;/a&gt; is &lt;a href=&quot;/journal/how-plan-mode-builds-a-checklist/&quot;&gt;documented in a separate post&lt;/a&gt;. Across the catalogue, if the algorithm is the product, people should be able to read it.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;a href=&quot;https://apps.apple.com/app/id6761336870&quot;&gt;Chessful is available on the App Store.&lt;/a&gt; The free tier includes 40 AI opponents, Stockfish analysis on every game, plain-language mistake summaries, and three training sessions per week. Premium unlocks unlimited deep analysis, unlimited adaptive training, full progress tracking with 90/180/365-day skill-trend graphs, and alternative-move exploration: $2.99/month, $17.99/year, or $29.99 once for lifetime access with a 7-day free trial. The companion design note on the forty AI opponents is &lt;a href=&quot;/journal/forty-chess-opponents/&quot;&gt;Forty chess opponents, and none of them are me&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>Why engine depth at club level should be tuned down, not up</title>
    <link href="https://lagerland-apps.github.io/journal/engine-depth-at-club-level-tune-down/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/engine-depth-at-club-level-tune-down/</id>
    <published>2026-05-13T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Every chess app advertises its engine depth. Chess.com&apos;s analysis runs to depth 22. Lichess Cloud reaches 28. Stockfish on a modern desktop will happily run depth 35 if you let it. This post explains why none of that helps an 800 to 1800 rated player improve, and why Chessful deliberately caps engine depth at the level where the mistakes that decide club games become visible, and goes no deeper.</summary>
    <content type="html">&lt;p&gt;Every chess app advertises its engine depth. Chess.com’s &lt;em&gt;Game Review&lt;/em&gt; runs Stockfish to depth 22. Lichess’s cloud analysis offers depth 28. Stockfish on a modern desktop will happily run depth 35 if you give it the time.&lt;/p&gt;

&lt;p&gt;Chessful runs Stockfish considerably shallower than any of them. It doesn’t have to; it does it because, for the players Chessful is made for, deeper analysis makes the training worse.&lt;/p&gt;

&lt;p&gt;Here is the argument. It’s a contrarian position in chess software, where “depth” is treated as a quality metric the way horsepower is in cars. Below roughly 2000 rating, &lt;strong&gt;engine depth above 15 ply produces lines that the user cannot read or apply.&lt;/strong&gt; The lines are correct, and nobody at that level can learn from them. The mistakes that decide games at 800-1800 are visible at depth 10-15, and deeper analysis surfaces subtleties that crowd them out.&lt;/p&gt;

&lt;p&gt;The choice has a measurable side effect: analysis runs fast on-device, which is what makes the iPhone, iPad, and Mac on-device promise possible. But the teaching reason came first.&lt;/p&gt;

&lt;h2 id=&quot;what-engine-depth-actually-means&quot;&gt;What “engine depth” actually means&lt;/h2&gt;

&lt;p&gt;In chess engine terminology, &lt;em&gt;depth&lt;/em&gt; is the number of half-moves (plies) the engine looks ahead. Depth 13 means the engine evaluates positions assuming both players will play their best moves for the next 13 ply (roughly 6 full moves for each side, give or take). Depth 25 means roughly 12 full moves of look-ahead.&lt;/p&gt;

&lt;p&gt;Each additional ply expands the search tree by a factor of roughly 4-5 (the &lt;em&gt;branching factor&lt;/em&gt; of chess after pruning). Going from depth 13 to depth 25 costs something like 10,000-50,000× more work, far more than double. Modern engines soften this with alpha-beta pruning, transposition tables and aggressive heuristics, but that cost growth is why cloud analysis exists at all: most depth-25 analyses are too expensive to run on a phone.&lt;/p&gt;

&lt;p&gt;Chess.com and Lichess can offer depth 22-28 because they run the analysis in the cloud, on rented compute, and send back the result. The cost is the cloud round-trip, plus, in Chess.com’s case, a daily quota on the deep analyses.&lt;/p&gt;

&lt;p&gt;Chessful runs Stockfish on-device, and its cost is the hardware: an iPhone has roughly 1/50th of the compute of a desktop, and deep analysis on a phone is slow enough to be unusable.&lt;/p&gt;

&lt;p&gt;Most people stop reasoning here. The usual version goes: “Chessful runs shallower because it has to; Chess.com / Lichess run deeper because they can.” Put like that, deeper is better and Chessful is making the best of a hardware limitation.&lt;/p&gt;

&lt;p&gt;That version is wrong, and the error matters, because it decides whether the training the app produces actually helps you improve. The real argument runs the other way.&lt;/p&gt;

&lt;h2 id=&quot;what-club-players-can-read&quot;&gt;What club players can read&lt;/h2&gt;

&lt;p&gt;Take a specific example. Imagine a position from a 1400 vs 1400 club game, move 18. The user has just played &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bd3&lt;/code&gt;, intending to bolster the kingside. Stockfish evaluates this position.&lt;/p&gt;

&lt;p&gt;At &lt;strong&gt;depth 12&lt;/strong&gt;, Stockfish reports: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eval -1.4. Best move: Qe2. Line: Qe2 Nf4 Bxf4 Qxf4 Rxe6.&lt;/code&gt; The line is five plies long, and the user can read it: queen to e2 defends, knight comes in, bishop trades, queen recaptures, rook lifts to take on e6. A five-move sequence is within calculation reach for a 1400 player. They can see why Qe2 was right (it stops Nf4 from being effective), play through the line on a board, and generalise it to “when the e-file is open and the queen is exposed, develop the queen toward the defence.”&lt;/p&gt;

&lt;p&gt;At &lt;strong&gt;depth 22&lt;/strong&gt;, Stockfish reports: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eval -1.9. Best move: Re1. Line: Re1 Nf4 Bxf4 Qxf4 Re5 Qg4 h3 Qxd1+ Kh2 Qxa1 Re8+ Rxe8 Qxa1&lt;/code&gt;. The line is 13 plies long. It begins with a quiet rook move that pays off ten moves later as a queen trade. The 1400 player cannot read this line. They cannot calculate to move 13 in their head, and playing through it on a board won’t show them why Re1 beats the Qe2 line the depth-12 engine recommended.&lt;/p&gt;

&lt;p&gt;Both engine recommendations are correct. The evaluations differ (-1.4 vs -1.9), but neither is wrong; each is Stockfish reading the position to its own horizon. What matters is which one teaches anything.&lt;/p&gt;

&lt;p&gt;For the 1400 player, the depth-12 line &lt;strong&gt;teaches them something&lt;/strong&gt; about defensive piece placement. The depth-22 line teaches them that the engine knows better than they do, which they already knew, and which gives them nothing to carry into the next game.&lt;/p&gt;

&lt;p&gt;That is the central claim: &lt;strong&gt;at club level, engine depth beyond what the user can calculate is noise.&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;why-the-noise-actively-harms-training&quot;&gt;Why the noise actively harms training&lt;/h2&gt;

&lt;p&gt;Deeper analysis does more than fail to help. It crowds out the help that’s available.&lt;/p&gt;

&lt;p&gt;Suppose the depth-22 analysis flags &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Re1&lt;/code&gt; as the best move and rates the user’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bd3&lt;/code&gt; as a “blunder” (the eval difference is greater than the platform’s blunder threshold). Suppose the depth-12 analysis flags &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Qe2&lt;/code&gt; as the best move and rates &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bd3&lt;/code&gt; as a “mistake” (a smaller eval drop, since the comparison is to a shorter calculation horizon).&lt;/p&gt;

&lt;p&gt;The depth-12 verdict is the more useful one. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bd3&lt;/code&gt; was a defensive misjudgement the user can recognise and drill: they missed the importance of getting the queen to e2 before letting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Nf4&lt;/code&gt; in. That’s a defender-placement motif, and it can be drilled and carried into the next game.&lt;/p&gt;

&lt;p&gt;The depth-22 verdict is technically correct and produces no training. “You should have played &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Re1&lt;/code&gt; for a 13-move forcing sequence” is not a lesson the player can absorb. It’s a fact about the position that changes nothing about how they play.&lt;/p&gt;

&lt;p&gt;Train a player on depth-22 analyses and they learn to nod at engine output and accept that the engine sees further than they do. They don’t learn to find better moves themselves. The engine’s accuracy ends up replacing the development of their own calculation.&lt;/p&gt;

&lt;h2 id=&quot;what-the-right-depth-is&quot;&gt;What the right depth is&lt;/h2&gt;

&lt;p&gt;For Chessful’s audience (800-1800 rating range), depth 12-15 is the band where:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The engine’s recommendations are short enough for a careful club player to calculate.&lt;/li&gt;
  &lt;li&gt;The mistakes the engine flags (hung pieces, missed tactics, defender-removal blindness, prophylactic skips, opposition errors) are the ones that decide games at this level.&lt;/li&gt;
  &lt;li&gt;The drills built from the analysis target patterns the player has a realistic chance of recognising in their next game.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At depth 13 specifically, Stockfish reliably finds:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;All hung pieces&lt;/strong&gt; (depth 2-3 is enough).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;All one-move tactics&lt;/strong&gt; (forks, pins, skewers): depth 3-5.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;All two-move forcing sequences&lt;/strong&gt; (most tactical combinations club players miss): depth 7-9.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Most three-move forcing sequences&lt;/strong&gt; (the long end of a club player’s tactical horizon): depth 11-13.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Defensive misjudgements whose consequences show up within 3-5 plies&lt;/strong&gt;: depth 10-13.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Depth 13 covers the whole calculation horizon of a typical club player’s actual games. Going deeper finds &lt;em&gt;additional&lt;/em&gt; mistakes, and those are also mistakes the player cannot fix.&lt;/p&gt;

&lt;p&gt;The balance shifts at the top of the club range. Around 1800-2000, players start to read longer engine lines reliably, and the right depth creeps up. By 2200, deeper analysis is genuinely useful. By 2400, players want depth 30+ because they can use it.&lt;/p&gt;

&lt;p&gt;Chessful’s audience is below that band, and for them the mistakes live at depth 13-15.&lt;/p&gt;

&lt;p&gt;Puzzle design uses the same idea in the other direction, with depth as the measure of what a player can use: in Millrace, every chapter is pinned to an exact shortest-solution depth, from five moves to ten or more, and &lt;a href=&quot;/journal/how-millrace-levels-are-made/&quot;&gt;the levels are generated and verified by search&lt;/a&gt; to guarantee it.&lt;/p&gt;

&lt;h2 id=&quot;the-hardware-side-effect&quot;&gt;The hardware side effect&lt;/h2&gt;

&lt;p&gt;Running Stockfish at depth 13 on an iPhone is fast. A modern A-series chip produces the analysis in roughly 0.5-2 seconds per move on a typical middlegame position. A full 50-move game analyses in 30-90 seconds, comfortably inside the “I closed the app and reopened it and it’s done” budget.&lt;/p&gt;

&lt;p&gt;Running Stockfish at depth 22 on the same phone is slow. The same game would take 5-20 minutes, the phone would be hot by the end, and the battery cost is real.&lt;/p&gt;

&lt;p&gt;So the speed follows from the teaching choice. Chessful’s analysis is fast on-device because depth 13 is fast on-device. The on-device-only promise (no cloud, no daily quota, no account) is &lt;em&gt;enabled&lt;/em&gt; by the depth choice, but the depth choice came first.&lt;/p&gt;

&lt;p&gt;If depth 22 produced better training for club players, Chessful would run depth 22 and accept the slower analysis and the battery cost. It would probably also have to fall back to cloud analysis on older phones, which would weaken the privacy story. That didn’t happen because depth 22 doesn’t produce better training; the privacy story was never ranked above the training. The teaching choice and the privacy story happen to point the same way.&lt;/p&gt;

&lt;h2 id=&quot;what-deeper-analysis-is-useful-for&quot;&gt;What deeper analysis is useful for&lt;/h2&gt;

&lt;p&gt;Deep engine analysis has real uses:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Players above 2000 rating&lt;/strong&gt;, whose calculation horizons extend into the 6-12 ply range.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Opening preparation&lt;/strong&gt;, where you want the objectively best moves in book positions you’ll see again.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Correspondence chess&lt;/strong&gt;, where the time control lets the player actually work through engine lines.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Engine vs engine games&lt;/strong&gt;, where the goal is engine accuracy, and human improvement doesn’t come into it.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Theoretical exploration&lt;/strong&gt;, where the question is “what is the truth of this position” and not “what should this player do next.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these apply to club-level improvement. That training aims to fix the patterns the player gets wrong in actual games, and those patterns are visible at depth 13. Deeper analysis adds patterns the player cannot act on.&lt;/p&gt;

&lt;p&gt;The chess software industry settled on “more depth = better app” for two reasons. Depth is an easy metric to compete on (rent more cloud compute). And the most visible chess players, titled players, streamers and content creators, can use deeper analysis and praise it accordingly. The metric became a marketing claim before anyone asked whether it served the median user.&lt;/p&gt;

&lt;p&gt;Chessful is betting that the median user is better served by training they can read.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;a href=&quot;https://apps.apple.com/app/id6761336870&quot;&gt;Chessful is available on the App Store.&lt;/a&gt; The full training method, including how Stockfish output becomes motif classifications and spaced-repetition drills, is in &lt;a href=&quot;/journal/how-chessful-builds-adaptive-training/&quot;&gt;How Chessful turns a Stockfish evaluation into adaptive training&lt;/a&gt;. The complete catalogue of the 30 mistake motifs the analyser flags is in &lt;a href=&quot;/journal/30-chess-mistake-motifs/&quot;&gt;The 30 chess mistake motifs Chessful detects&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>Countdown psychology: why anticipation beats reminders</title>
    <link href="https://lagerland-apps.github.io/journal/countdown-psychology-why-anticipation-beats-reminders/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/countdown-psychology-why-anticipation-beats-reminders/</id>
    <published>2026-05-13T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">There&apos;s a sleep researcher&apos;s joke that the best part of a holiday is the planning of it. It&apos;s funnier because it&apos;s defensible: looking forward to something is one of the most reliably positive emotional states a person can be in, and it costs nothing. This post covers why countdown apps work, why anticipation motivates better than reminders do, and what a countdown should do with the space it takes up on your phone.</summary>
    <content type="html">&lt;p&gt;Tourism researchers established something about fifteen years ago that the holiday-planning industry knows but rarely mentions: statistically, the happiest part of a vacation is the lead-up.&lt;/p&gt;

&lt;p&gt;Jeroen Nawijn’s 2010 study &lt;em&gt;“The holiday happiness curve: a preliminary investigation into mood during a holiday abroad”&lt;/em&gt; tracked holidaymakers’ mood across the whole trip, before, during, and after. The resulting chart is well known in the field. Happiness peaks in the &lt;strong&gt;pre-trip&lt;/strong&gt; weeks, sometimes higher than during the trip and reliably higher than after. The post-trip dip is real, and so is the happiness mid-trip. But the most reliable and longest-lasting positive affect comes in the weeks of anticipation before departure.&lt;/p&gt;

&lt;p&gt;The same holds outside holidays. Weddings, births, graduations, moves, long-planned reunions, big concerts, and retirement all have this emotional shape. The lead-up is a reward of its own, separate from the event and often longer-lasting.&lt;/p&gt;

&lt;p&gt;Countdown apps are a way to collect that reward.&lt;/p&gt;

&lt;p&gt;Below: what the research says about anticipation as a motivational and emotional state, why it works better than reminders for this kind of event, and what a countdown should do with the space it takes up on a phone’s Home Screen.&lt;/p&gt;

&lt;h2 id=&quot;what-the-research-says&quot;&gt;What the research says&lt;/h2&gt;

&lt;p&gt;George Loewenstein, an economist at Carnegie Mellon, formalised &lt;strong&gt;anticipatory utility&lt;/strong&gt; in 1987 in a paper called &lt;em&gt;“Anticipation and the Valuation of Delayed Consumption.”&lt;/em&gt; The setup was simple. Subjects chose when they would prefer to receive a defined future reward (in Loewenstein’s case, a kiss from a movie star of their choosing). Standard economic theory predicted everyone would pick “as soon as possible”, following delay discounting, the same logic that makes a dollar today worth more than a dollar in a year.&lt;/p&gt;

&lt;p&gt;Loewenstein found that a significant fraction of subjects chose to delay the reward. They still wanted it; they also wanted to &lt;strong&gt;savour&lt;/strong&gt; the anticipation. Looking forward to the kiss was a source of utility in its own right, and they were willing to pay for a longer anticipation phase with delayed gratification.&lt;/p&gt;

&lt;p&gt;The finding has been replicated and extended in many domains:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Van Boven and Gilovich (2003)&lt;/strong&gt; found that subjects who reflected on past experiential purchases (trips, concerts, dinners) felt more positive than those reflecting on material purchases (electronics, clothes). They proposed that experiences give utility in three phases, anticipation, consumption, and memory, and that anticipation is often the strongest of them.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Nawijn (2010, 2011)&lt;/strong&gt; showed empirically that holidaymakers report higher subjective well-being in the lead-up to a trip than during or after it.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Sevdalis and Harvey (2007)&lt;/strong&gt; found that anticipation effects hold even when participants are unsure whether the event will happen at all, a kind of pre-emptive enjoyment.&lt;/li&gt;
  &lt;li&gt;More recent positive psychology calls this &lt;strong&gt;prospection&lt;/strong&gt;, the brain’s capacity to simulate future positive states, and counts it among the four pillars of well-being, alongside connection, meaning, and engagement.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So anticipation is a form of consumption in its own right, and the wait is part of the experience.&lt;/p&gt;

&lt;h2 id=&quot;why-anticipation-outperforms-reminders&quot;&gt;Why anticipation outperforms reminders&lt;/h2&gt;

&lt;p&gt;Reminders and countdowns look alike, since both put a future event on your phone, but they set up different psychological frames.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;reminder&lt;/strong&gt; frames a future task as an &lt;strong&gt;obligation&lt;/strong&gt;. The implicit verb is &lt;em&gt;do&lt;/em&gt;: “remember to do this thing.” The feeling it carries is neutral at best and mildly unpleasant at worst. People often turn reminders off, ignore them, or dismiss them angrily, especially when there are many. A reminder is a debt.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;countdown&lt;/strong&gt; frames a future event as a &lt;strong&gt;reward&lt;/strong&gt;. The implicit verb is &lt;em&gt;expect&lt;/em&gt;: “this thing is coming.” The feeling is positive. People keep countdowns in view, photograph them to send to friends, and screenshot them at milestones. A countdown is a savings account.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;same future event&lt;/em&gt; can arrive through either frame, and people respond to the two in measurably different ways. “Wedding in 30 days” in a generic reminder app reads as a low-grade panic prompt. “Wedding in 30 days” with a full-bleed photo of the venue, a Plan Mode checklist that handles the prep and a widget you glance at over morning coffee reads as something you’re glad about.&lt;/p&gt;

&lt;p&gt;Reminders still have their place. They suit &lt;strong&gt;negative or neutral obligations&lt;/strong&gt;: bills, recurring chores, appointments you have to keep whether you want to or not. A reminder is the right frame for the dentist.&lt;/p&gt;

&lt;p&gt;Countdowns suit &lt;strong&gt;positive future events&lt;/strong&gt;, where the lead-up is part of the reward. A reminder is the wrong frame for a honeymoon.&lt;/p&gt;

&lt;p&gt;Most countdown apps fail because they are built like reminders. They make the number bigger, ship widgets, and add a theme picker, but they still treat the date as an obligation to manage. The photo is missing, the checklist is generic, and the notifications fire daily. Anticipation ends up feeling like work.&lt;/p&gt;

&lt;p&gt;They should be designed for savouring.&lt;/p&gt;

&lt;h2 id=&quot;what-a-good-countdown-does&quot;&gt;What a good countdown does&lt;/h2&gt;

&lt;p&gt;It needs three things, listed here in priority order. Get any one of them wrong and the app stops working as a source of anticipation.&lt;/p&gt;

&lt;h3 id=&quot;1-a-sensory-anchor&quot;&gt;1. A sensory anchor&lt;/h3&gt;

&lt;p&gt;The countdown needs a photograph the user picked of the specific future: the venue, the beach, the maternity ward, the new apartment. A stock image or theme background doesn’t do the job. Anticipation runs on mental simulation, and simulation runs on sensory cues. “30 days until vacation” is abstract; “30 days until [photo of the actual hotel pool you booked]” is concrete.&lt;/p&gt;

&lt;p&gt;So in this category the full-bleed photo background carries much of the emotional weight. Without it the countdown is a number. With it, each day becomes a small rehearsal of the event.&lt;/p&gt;

&lt;h3 id=&quot;2-a-sense-of-agency&quot;&gt;2. A sense of agency&lt;/h3&gt;

&lt;p&gt;The countdown needs a checklist that handles the prep, and it should know what kind of event this is and what the prep rhythm looks like. A generic to-do list won’t do.&lt;/p&gt;

&lt;p&gt;The reason is anxiety. A bare countdown to a wedding often makes people slightly anxious: they know the date but not the path, and the distance between the two grows as the day approaches. A countdown that comes with a plan closes that distance. The number stops saying “you should be doing something” and starts saying where you are: “you are 21 days out, and here is what 21 days out looks like.”&lt;/p&gt;

&lt;p&gt;The checklist also gives the anticipation a &lt;em&gt;path&lt;/em&gt;. You cross off “send save-the-dates” and feel, fairly, that the wedding has partly started. Anticipation combined with progress keeps the good feeling going much longer than anticipation alone.&lt;/p&gt;

&lt;h3 id=&quot;3-one-notification-per-task-not-one-per-day&quot;&gt;3. One notification per task, not one per day&lt;/h3&gt;

&lt;p&gt;Most of the time, a good countdown should &lt;strong&gt;stay quiet&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Countdown apps shaped like reminders all fail the same way, with a daily “X days to go!” notification. The first one feels good and the second one is fine. By the seventh, the user has turned off the app’s banners. One notification a day for 90 days gives you 90 notifications and one useful signal.&lt;/p&gt;

&lt;p&gt;A good countdown notifies &lt;em&gt;only on the day a Plan Mode task is due&lt;/em&gt;. T-30 has a “book transport” prompt, T-14 has “buy travel adapter, check passport expiry”, and T-7 has “refill prescriptions.” Over a trip month the user gets six or seven notifications, each one actionable on the day it arrives. The rest of the time the countdown sits on widgets (Home Screen, Lock Screen, StandBy), visible without interrupting.&lt;/p&gt;

&lt;p&gt;Anticipation lasts when the event stays quietly in view, and interruptions wear it down.&lt;/p&gt;

&lt;h2 id=&quot;what-this-means-for-product-designers&quot;&gt;What this means for product designers&lt;/h2&gt;

&lt;p&gt;If your product involves a positive future event, whether it’s a planning app, a booking app, a goal tracker, or a course-completion app, you are probably not using the countdown frame enough.&lt;/p&gt;

&lt;p&gt;Some specific implications:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Anywhere you have a “deadline” or “due date” UI, ask whether the user wants a deadline frame or an anticipation frame.&lt;/strong&gt; Course completion, fitness milestones, savings goals, and product launches are mostly positive events the user looks forward to, and the UI should treat them that way. A photo on a savings goal page (the apartment, the trip, the camera) does real emotional work in that feature.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Separate reminder-frame and countdown-frame events in the data layer.&lt;/strong&gt; They need different defaults, notification cadences, and visual treatments. Mixing them in one “events” model produces a UI that pleases no one.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Limit notifications to task days by default.&lt;/strong&gt; Most users will never change this setting themselves, so the default has to be quiet.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Treat the run-up as part of the product.&lt;/strong&gt; The experience starts when the user creates the event. Design the 30-day or 90-day run-up as a feature, and don’t let it become a loading bar.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of this is radical. It is what Loewenstein, Nawijn, Van Boven, and Gilovich’s findings look like when applied to product design, and it applies well beyond countdown apps.&lt;/p&gt;

&lt;h2 id=&quot;how-soon-applies-this&quot;&gt;How Soon. applies this&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/apps/soon/&quot;&gt;Soon.&lt;/a&gt; exists because none of the major countdown apps treat anticipation as the main thing they offer; they treat it as a number to display. Soon. is built around the three components above: the photo, the plan, and the notification rule. That follows from what the research says makes a countdown worth having.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/journal/how-plan-mode-builds-a-checklist/&quot;&gt;Plan Mode&lt;/a&gt;, the part of Soon. that ships event-type templates and schedules tasks backward from the event date, provides the agency. The full-bleed photo background is the sensory anchor. The one-notification-per-task rule (Premium) keeps notifications down.&lt;/p&gt;

&lt;p&gt;This post is mainly for anyone building products in this space: countdowns deserve to be taken seriously as support for looking forward to good events, more than as a novelty UI element. The research is decades old, and most products in the space still just display a number.&lt;/p&gt;

&lt;p&gt;Few tools treat anticipation as the main experience, and there is room for many more. We expect the next generation of planning, productivity, and life-events apps to be built on this idea, and the psychology is the place to start.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;a href=&quot;https://apps.apple.com/app/id6757280643&quot;&gt;Soon. is available on the App Store.&lt;/a&gt; Free for up to 5 events, with no time limit; Premium adds Apple WeatherKit destination forecasts, daily notes, recurring events, and one-task-per-day Plan Mode notifications. The full set of event-type templates (Trip, Wedding, Pregnancy, Birthday, Graduation, Move) is documented in &lt;a href=&quot;/journal/how-plan-mode-builds-a-checklist/&quot;&gt;How Plan Mode builds a checklist&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>Why your Apple Watch HRV number means almost nothing without a baseline</title>
    <link href="https://lagerland-apps.github.io/journal/apple-watch-hrv-without-a-baseline/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/apple-watch-hrv-without-a-baseline/</id>
    <published>2026-05-13T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">A 42ms HRV reading on Apple Watch can be excellent, average, or alarming, and you can&apos;t tell which without context. On its own, the number is one of the most misread metrics in consumer health. This post covers what HRV tells you, what it doesn&apos;t, and why a personal baseline is the only frame that makes the reading usable.</summary>
    <content type="html">&lt;p&gt;Apple Watch measures one of the most informative numbers in consumer physiology, and almost nobody uses it correctly.&lt;/p&gt;

&lt;p&gt;Open the Health app and tap Heart Rate Variability. You’ll see a column of numbers from the last few weeks, probably some 25s, some 45s, some 80s, and a “Range” chart that looks vaguely informative. If you’ve fallen into the wrong corner of the internet, you may have read that HRV “should” be above 50ms or that anything below 30 is “concerning.” That is about as useful as being told your “normal” body temperature should be 99°F regardless of who you are. The number is real. The frame is wrong.&lt;/p&gt;

&lt;h2 id=&quot;what-hrv-actually-measures&quot;&gt;What HRV actually measures&lt;/h2&gt;

&lt;p&gt;HRV, or heart-rate variability, is the variation in time between consecutive heartbeats. Apple Watch reports SDNN, the standard deviation of the intervals between successive normal heartbeats (the NN, or RR, intervals), in milliseconds. Higher generally means more parasympathetic (“rest-and-digest”) nervous-system activity, and lower generally means more sympathetic (“fight-or-flight”) activity. A consistently higher trend correlates with cardiovascular fitness, recovery quality, and parasympathetic dominance.&lt;/p&gt;

&lt;p&gt;So far, so good. The trouble starts when the same words apply to two people whose absolute numbers differ by a factor of three.&lt;/p&gt;

&lt;h2 id=&quot;the-variation-between-people-is-enormous&quot;&gt;The variation between people is enormous&lt;/h2&gt;

&lt;p&gt;Absolute HRV in healthy adults ranges roughly from 15ms to 150ms in SDNN terms, a 10× spread. These factors move someone’s individual baseline:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Age.&lt;/strong&gt; Most longitudinal studies find HRV declines roughly 0.5 to 1ms per year after age 30. A 45-year-old with 35ms HRV and a 25-year-old with 70ms may both be in perfect parasympathetic health for their age.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Sex.&lt;/strong&gt; Average HRV is somewhat lower in adult women than men, though the variation within each sex is much larger than the difference between them.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Fitness level.&lt;/strong&gt; Endurance-trained people routinely show 50 to 100% higher resting HRV than untrained people. That isn’t proportionally informative either: well-conditioned athletes often sit in ranges a generic chart would call “elevated.”&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Body position.&lt;/strong&gt; HRV is higher lying down than seated, and higher seated than standing.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Time of day.&lt;/strong&gt; Higher overnight, lower during active hours.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Measurement method.&lt;/strong&gt; Apple Watch’s optical PPG at variable times produces different numbers than a chest strap or a research-grade ECG, even on the same person at the same moment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;HRV is one of those biological metrics where &lt;em&gt;yours&lt;/em&gt; is the only one that means anything. Comparing your 42ms to a friend’s 65ms tells you nothing.&lt;/p&gt;

&lt;h2 id=&quot;the-right-frame-your-own-60-day-baseline&quot;&gt;The right frame: your own 60-day baseline&lt;/h2&gt;

&lt;p&gt;The only HRV readings you can reliably interpret look like one of these:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;“Today’s HRV (SDNN) is X% above/below my own 7-day rolling average.”&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;“This week’s mean is X% above/below my own 60-day rolling average.”&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both compare you with yourself, which cancels out nearly every confounder above. Your age and sex don’t change in 60 days, your fitness doesn’t change dramatically, and your watch is the same watch. What does change is &lt;em&gt;whatever moved your physiology this week compared with last quarter&lt;/em&gt;, and that’s the question worth asking.&lt;/p&gt;

&lt;p&gt;Sixty days works as a baseline window for three reasons. It’s roughly two menstrual cycles, so cyclical variation averages out. It covers two typical training mesocycles, so short-term adaptation doesn’t dominate. And it gives enough non-overlapping weekly samples for a standard deviation to mean something; with fewer, the SD itself is noisy.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/apps/observa/&quot;&gt;Observa&lt;/a&gt; uses this baseline window, and so do most peer-reviewed sports-science HRV studies, for the same reasons.&lt;/p&gt;

&lt;h2 id=&quot;what-a-single-low-reading-does-and-doesnt-mean&quot;&gt;What a single low reading does and doesn’t mean&lt;/h2&gt;

&lt;p&gt;A morning where your HRV is 30% below your 7-day average means &lt;em&gt;something happened&lt;/em&gt;: late food, alcohol, poor sleep, a stressful evening, the start of an illness, hard training the day before, or ordinary day-to-day biological noise. By itself it doesn’t tell you to rest, train hard, panic, or rejoice.&lt;/p&gt;

&lt;p&gt;A &lt;em&gt;pattern&lt;/em&gt; is diagnostic. Three consecutive days more than one standard deviation below baseline is signal. A single 25% drop after a known stressor tells you about that stressor, not your health. A 25% drop with no identifiable cause that hasn’t resolved within 72 hours warrants attention, from a clinician and not a consumer app.&lt;/p&gt;

&lt;p&gt;For self-experimentation, I think this threshold is roughly right: &lt;strong&gt;at least 10 same-condition observations across a 60-day window, and at least one standard deviation of separation between conditions&lt;/strong&gt;, before you treat a finding as anything but noise. Most consumer apps surface “insights” with far thinner statistical backing, which is mostly why those insights are mostly wrong.&lt;/p&gt;

&lt;h2 id=&quot;why-hrv-drops-in-winter-and-other-seasonal-noise&quot;&gt;Why HRV drops in winter (and other seasonal noise)&lt;/h2&gt;

&lt;p&gt;If you wear an Apple Watch through a northern-hemisphere winter, expect your HRV baseline to drop 10 to 20% from October to February. The usual causes are cold exposure, less daylight, less aerobic activity, more time indoors, and altered sleep. None of them is pathological, and all of them pull the number down.&lt;/p&gt;

&lt;p&gt;Reading a winter dip as “I’m broken” is one of the most common interpretation mistakes. The correct reading is “winter HRV runs lower for me, and here’s the new baseline to measure deviations from.” The baseline is supposed to drift, because your physiology drifts with the world.&lt;/p&gt;

&lt;h2 id=&quot;what-this-means-in-practice&quot;&gt;What this means in practice&lt;/h2&gt;

&lt;p&gt;A few practical rules follow from all this:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Never compare your number to anyone else’s.&lt;/strong&gt; Not a friend’s, not a stranger’s on Reddit, not a “normal range” infographic. Compare yourself to yourself.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Track trends.&lt;/strong&gt; A single day’s HRV is mostly noise. The 7-day rolling mean is signal, and the 60-day baseline is the frame that makes the signal interpretable.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Read it as a deviation from your own baseline.&lt;/strong&gt; HRV is roughly log-normally distributed, so the same millisecond gap means more at a low baseline than a high one. Expressing today’s SDNN as a percentage deviation from your personal rolling mean is what makes it interpretable.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Identify your stressors.&lt;/strong&gt; If your HRV consistently drops after late workouts, alcohol, or long screen time, you can act on that. The drop isn’t the problem; the unknown cause is.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Expect seasonal drift.&lt;/strong&gt; Lower in winter and higher in summer is normal. A pandemic, an illness, life stress, or a new baby will all move the baseline too. Treat it as a moving frame of reference.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href=&quot;/apps/observa/&quot;&gt;Observa&lt;/a&gt; does this automatically. It computes your 60-day rolling HRV (SDNN) baseline, scores each day’s reading against your own deviation, and tells you in plain English when something is genuinely outside your normal range and when it isn’t. Everything runs on-device, so the only comparison Observa ever makes is &lt;em&gt;you, today, against you, on average&lt;/em&gt;, which is the only HRV comparison worth making.&lt;/p&gt;

&lt;h2 id=&quot;tldr&quot;&gt;TL;DR&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Absolute HRV varies 3 to 10× between healthy adults.&lt;/strong&gt; Comparing your number to anyone else’s is meaningless.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Your 60-day rolling baseline is the only frame that makes HRV usable.&lt;/strong&gt; Day-to-day swings of 10 to 25% are normal.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Trends matter; single points don’t.&lt;/strong&gt; Three consecutive days more than one SD below baseline is signal. One day is noise.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Winter HRV runs lower than summer.&lt;/strong&gt; Seasonal drift is normal, and treating it as illness is the common error.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Read SDNN as a deviation from your own baseline.&lt;/strong&gt; HRV is roughly log-normally distributed, so compare each day to your personal mean as a percentage, not to raw millisecond thresholds.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The number has always been in your Health app. What was missing is a baseline to read it against.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>The 6 Apple Health metrics worth interpreting (and the 12 worth ignoring)</title>
    <link href="https://lagerland-apps.github.io/journal/apple-health-metrics-worth-interpreting/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/apple-health-metrics-worth-interpreting/</id>
    <published>2026-05-13T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Apple Health collects more than 80 distinct health metrics. Most of them are noise, vanity numbers, or sensor data you have no useful frame for. This is the short list: the six that move with your habits and reward interpretation, the twelve that look meaningful but mostly aren&apos;t, and how to tell the two apart.</summary>
    <content type="html">&lt;p&gt;Apple Health has become, almost by accident, the largest passively collected health dataset most people will ever own. The watch on your wrist measures more than 80 distinct signals across heart rate, activity, sleep, environmental exposure, mobility, and mindfulness, and most of them are noise.&lt;/p&gt;

&lt;p&gt;That says less about Apple Health than about how consumer health apps display data they have no frame for. Using Apple Health well means knowing which numbers are worth tracking against a personal baseline, and which you can stop opening the app to check.&lt;/p&gt;

&lt;p&gt;Below is the short list, with the reasoning for each cut.&lt;/p&gt;

&lt;h2 id=&quot;the-6-that-reward-interpretation&quot;&gt;The 6 that reward interpretation&lt;/h2&gt;

&lt;p&gt;With these metrics, consistent attention pays back in actual self-knowledge. Each has good signal-to-noise on weekly timescales, moves measurably with habits you control, and has a baseline stable enough that deviations mean something.&lt;/p&gt;

&lt;h3 id=&quot;1-hrv-sdnn&quot;&gt;1. HRV (SDNN)&lt;/h3&gt;

&lt;p&gt;Heart-rate variability is the single most informative metric Apple Watch collects. The watch records it as SDNN, the standard deviation of the intervals between successive heartbeats. It folds autonomic nervous system state, recovery, training adaptation, alcohol load, sleep quality, and acute stress into one number, and it changes measurably within 24 to 48 hours of a habit shift.&lt;/p&gt;

&lt;p&gt;The caveat is that it only means something against your own 60-day baseline, because absolute HRV (SDNN) varies wildly between people. See &lt;a href=&quot;/journal/apple-watch-hrv-without-a-baseline/&quot;&gt;the dedicated post on why&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;2-resting-heart-rate-rhr&quot;&gt;2. Resting heart rate (RHR)&lt;/h3&gt;

&lt;p&gt;RHR moves more slowly than HRV but is easier to interpret. Apple Watch reports an averaged RHR that smooths nicely over a week. It’s useful for spotting:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Aerobic fitness trends (drops of 5 to 10 bpm over 3 to 6 months of consistent cardio)&lt;/li&gt;
  &lt;li&gt;Pre-illness signals (a sustained 5 to 10 bpm above baseline often comes 24 to 48 hours before a cold)&lt;/li&gt;
  &lt;li&gt;Alcohol load (RHR routinely rises 5 to 15 bpm the morning after drinking)&lt;/li&gt;
  &lt;li&gt;Training overreaching (sustained elevation with no obvious cause)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Read it as a 7-day rolling average against your 60-day baseline, not as a daily number.&lt;/p&gt;

&lt;h3 id=&quot;3-sleep-efficiency&quot;&gt;3. Sleep efficiency&lt;/h3&gt;

&lt;p&gt;This is the percentage of time in bed you’re actually asleep. Apple Watch sleep tracking is mediocre at staging but very good at total time. Sleep efficiency above 90% is excellent; if it’s consistently below 80%, that often points to wind-down issues, caffeine timing, or anxiety.&lt;/p&gt;

&lt;p&gt;It holds up even after a short night, and it’s one of the easiest sleep numbers to act on: small wind-down changes typically move it 3 to 5 percentage points within two weeks.&lt;/p&gt;

&lt;h3 id=&quot;4-deep-sleep-share&quot;&gt;4. Deep-sleep share&lt;/h3&gt;

&lt;p&gt;This is the fraction of your night spent in slow-wave sleep. Apple Watch sleep staging is approximate, but the trend is reliable. Most physical recovery and memory consolidation happen in deep sleep, and alcohol, late workouts, late food, and bedroom temperature disrupt it more than any other stage.&lt;/p&gt;

&lt;p&gt;What moves it, roughly in order of impact: alcohol within 3 hours of bed (20 to 40% less), a workout after 18:00 (10 to 20% less), a large late meal (10 to 15% less), a warm bedroom (5 to 15% less), and heavy screen exposure within 30 minutes of sleep onset (5 to 25% less).&lt;/p&gt;

&lt;h3 id=&quot;5-heart-rate-dip-during-sleep&quot;&gt;5. Heart-rate dip during sleep&lt;/h3&gt;

&lt;p&gt;This is the percentage your heart rate drops from the daytime resting average to the overnight average. A dip of 15 to 25% is typical. Dips that stay below 10% can indicate poor sleep quality even when the headline “hours slept” looks fine.&lt;/p&gt;

&lt;p&gt;AutoSleep popularised this metric and almost nobody else surfaces it, yet for many people it correlates more strongly with subjective recovery than total sleep duration does. Apple Health has the data; you have to compute it yourself or use an app that does.&lt;/p&gt;

&lt;h3 id=&quot;6-active-energy-weekly&quot;&gt;6. Active energy (weekly)&lt;/h3&gt;

&lt;p&gt;Daily active calories are too noisy and too dependent on measurement accuracy. The weekly rolling total is one of the cleaner load metrics in Apple Health. Use it for:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Spotting training-load creep (week-over-week increases above 10% predict overuse injury risk)&lt;/li&gt;
  &lt;li&gt;Identifying recovery weeks (planned drops of 30 to 40%)&lt;/li&gt;
  &lt;li&gt;Long-term consistency, which is what moves cardiovascular fitness&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Read it weekly, since the daily figure is mostly noise.&lt;/p&gt;

&lt;h2 id=&quot;the-12-worth-ignoring-or-skimming-at-best&quot;&gt;The 12 worth ignoring (or skimming at best)&lt;/h2&gt;

&lt;p&gt;These metrics &lt;em&gt;look&lt;/em&gt; meaningful but mostly aren’t. Some are fine as adherence prompts and give you nothing to interpret. Others carry enough sensor error or definitional ambiguity that they cost more attention than they pay back.&lt;/p&gt;

&lt;h3 id=&quot;7-daily-step-count&quot;&gt;7. Daily step count&lt;/h3&gt;

&lt;p&gt;Step count is a near-perfect proxy for “did you wear your watch today.” It depends on phone-in-pocket vs watch-on-wrist, on where you live (urban walkers vs suburban drivers), and on what counts as a step (treadmill desks generate phantom counts). 8,000 mostly deliberate steps beat 14,000 of urban drift, and the number can’t tell them apart.&lt;/p&gt;

&lt;h3 id=&quot;8-move-ring-closure&quot;&gt;8. Move ring closure&lt;/h3&gt;

&lt;p&gt;The ring prompts adherence and offers nothing to interpret. It helps you get started and stops being useful once the habit has stuck.&lt;/p&gt;

&lt;h3 id=&quot;9-stand-hours&quot;&gt;9. Stand hours&lt;/h3&gt;

&lt;p&gt;Apple’s algorithm credits one minute of standing per hour for 12 hours. It’s generously calibrated, easy to game, and doesn’t correlate with anything else.&lt;/p&gt;

&lt;h3 id=&quot;10-daily-exercise-minutes&quot;&gt;10. Daily exercise minutes&lt;/h3&gt;

&lt;p&gt;Apple’s “exercise minute” counts any minute at brisk-walk heart rate or above. That’s adequate for tracking aerobic adherence and unreliable for strength training (little heart-rate elevation despite high muscular load), gentle yoga, or skill sports.&lt;/p&gt;

&lt;h3 id=&quot;11-vo2-max-estimated&quot;&gt;11. VO2 Max (estimated)&lt;/h3&gt;

&lt;p&gt;Useful, but it moves quarterly, and the day-to-day variation in the estimate is almost entirely noise. Check it monthly and leave it alone the rest of the time.&lt;/p&gt;

&lt;h3 id=&quot;12-cardio-recovery&quot;&gt;12. Cardio recovery&lt;/h3&gt;

&lt;p&gt;This is the 1-minute heart-rate recovery after exercise. Apple Watch’s calculation depends on whether you stop moving at the right moment. Even when it’s measured well, individual variation is high and the baseline shifts with fitness over months. It has uses in clinical contexts and is mostly noise in consumer use.&lt;/p&gt;

&lt;h3 id=&quot;13-daily-resting-energy&quot;&gt;13. Daily resting energy&lt;/h3&gt;

&lt;p&gt;This is Apple’s estimate of your basal metabolic rate, derived from height, weight, age, and sex. It’s a formula, so it changes only when you update your profile.&lt;/p&gt;

&lt;h3 id=&quot;14-walking-heart-rate-average&quot;&gt;14. Walking heart-rate average&lt;/h3&gt;

&lt;p&gt;A useful sanity check for fitness trends over 6+ months, and too noisy to read week over week.&lt;/p&gt;

&lt;h3 id=&quot;15-headphone-audio-exposure&quot;&gt;15. Headphone audio exposure&lt;/h3&gt;

&lt;p&gt;Useful for protecting your hearing. Beyond a “turn it down” reminder there’s nothing to act on, and the only question it answers is whether the number is high or low.&lt;/p&gt;

&lt;h3 id=&quot;16-environmental-sound-exposure&quot;&gt;16. Environmental sound exposure&lt;/h3&gt;

&lt;p&gt;The same applies here: good for protection, not for self-knowledge.&lt;/p&gt;

&lt;h3 id=&quot;17-mindful-minutes&quot;&gt;17. Mindful minutes&lt;/h3&gt;

&lt;p&gt;If you meditate, log it. The metric is a participation count, so there’s no signal-vs-noise question: you either meditated or you didn’t.&lt;/p&gt;

&lt;h3 id=&quot;18-daily-flights-climbed&quot;&gt;18. Daily flights climbed&lt;/h3&gt;

&lt;p&gt;A general activity number that depends heavily on whether you live in a building with stairs. There’s no frame for interpreting it.&lt;/p&gt;

&lt;h2 id=&quot;how-to-tell-the-difference&quot;&gt;How to tell the difference&lt;/h2&gt;

&lt;p&gt;To decide whether an Apple Health metric is worth interpreting, ask:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Does it have a 60-day baseline?&lt;/strong&gt; Quarterly-moving metrics (VO2 Max, body weight) don’t.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Does it move measurably with habits you control?&lt;/strong&gt; Step count doesn’t, really. HRV does.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Is the measurement error smaller than the signal you’re looking for?&lt;/strong&gt; Sleep efficiency error is ~3 percentage points and its signal is 5 to 15 percentage points. Active calories error is ±20 to 30%, and the daily signal is often smaller than that.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Is the baseline stable across seasons and life events?&lt;/strong&gt; If not, you’re tracking environmental noise.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Can you act on a deviation?&lt;/strong&gt; If a 20% drop in the metric wouldn’t change anything you do, don’t track it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Six metrics pass all five tests. About a dozen pass one or two. The rest are vanity numbers, adherence counts, or sensor data that looks like insight and isn’t.&lt;/p&gt;

&lt;h2 id=&quot;what-an-interpretation-app-actually-does&quot;&gt;What an interpretation app actually does&lt;/h2&gt;

&lt;p&gt;Most consumer health apps put 30+ metrics on a dashboard for product reasons, not scientific ones: more numbers look like more value. A useful interpretation app shows six because every extra number pulls attention toward noise.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/apps/observa/&quot;&gt;Observa&lt;/a&gt; is built around the short list. It computes rolling 60-day baselines for the six metrics that reward attention, surfaces correlations between your habits and those metrics, and ignores the rest. Apple Health still collects step count, move-ring closure, and stand hours, but Observa gives them no dashboard tile and doesn’t make you stare at them.&lt;/p&gt;

&lt;p&gt;For most people, getting self-knowledge out of Apple Health is less about tracking more and more about &lt;em&gt;subtracting&lt;/em&gt;. The data has been collecting itself for years. The hard part is deciding which numbers deserve your weekly attention and politely ignoring the rest.&lt;/p&gt;

&lt;h2 id=&quot;tldr&quot;&gt;TL;DR&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The 6 worth interpreting&lt;/strong&gt;, each on a 60-day personal baseline:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;HRV (SDNN)&lt;/strong&gt;: the single most informative number&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Resting heart rate&lt;/strong&gt;: signals illness and fitness trends&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Sleep efficiency&lt;/strong&gt;: the most actionable sleep metric&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Deep-sleep share&lt;/strong&gt;: what most habits actually move&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Heart-rate dip during sleep&lt;/strong&gt;: an under-used recovery signal&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Active energy (weekly)&lt;/strong&gt;: a clean training-load measure&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;The 12 worth ignoring or skimming&lt;/strong&gt;: step count, move ring, stand hours, daily exercise minutes, VO2 Max (weekly), cardio recovery, daily resting energy, walking heart rate, headphone exposure, sound exposure, mindful minutes, daily flights climbed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The 60+ others&lt;/strong&gt; Apple Health offers are probably not worth your weekly attention either, unless you’re a researcher with a specific question.&lt;/p&gt;

&lt;p&gt;In short: pick six metrics, read them against sixty-day baselines, and treat everything else as noise.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>App Store screenshot guidelines (2026): sizes, requirements, and what gets rejected</title>
    <link href="https://lagerland-apps.github.io/journal/app-store-screenshot-review-guidelines-explained/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/app-store-screenshot-review-guidelines-explained/</id>
    <published>2026-05-13T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Two sets of App Store screenshot rules get apps rejected or sent back for a re-upload: the technical specs (which sizes, how many, what format) and Review Guideline §2.3.3 (what the screen is allowed to show). This post covers both: the current 2026 specifications, and what each content clause means in practice.</summary>
    <content type="html">&lt;p&gt;App Store screenshots hold up apps for two unrelated reasons, and most guides only cover one. The first is technical: wrong size, wrong format, or a missing required device, and App Store Connect bounces the upload before a human sees it. The second is editorial. The screenshot uploads fine, a reviewer decides the screen isn’t showing the real app, and at 2 AM the night before launch you get the polite “your screenshots don’t appear to show actual functionality” rejection.&lt;/p&gt;

&lt;p&gt;Below are the current specifications first, then a working developer’s read of Review Guideline §2.3.3: which patterns reliably pass and which get rejected.&lt;/p&gt;

&lt;h2 id=&quot;app-store-screenshot-specifications-2026&quot;&gt;App Store screenshot specifications (2026)&lt;/h2&gt;

&lt;p&gt;The biggest change: &lt;strong&gt;you only need one iPhone size now.&lt;/strong&gt; Apple scales a single 6.9-inch (or 6.5-inch) set down to every smaller iPhone automatically, so you no longer export separate 6.7-inch, 6.5-inch, and 5.5-inch bundles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;iPhone, required (pick one):&lt;/strong&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Display&lt;/th&gt;
      &lt;th&gt;Portrait dimensions&lt;/th&gt;
      &lt;th&gt;Devices&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;6.9-inch&lt;/td&gt;
      &lt;td&gt;1320 × 2868 · 1290 × 2796 · 1260 × 2736&lt;/td&gt;
      &lt;td&gt;iPhone 17 / 16 Pro Max, Plus models&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;6.5-inch&lt;/td&gt;
      &lt;td&gt;1242 × 2688 · 1284 × 2778&lt;/td&gt;
      &lt;td&gt;iPhone 14 Plus, 13/12 Pro Max, XS Max&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Provide one of those, and the 6.3-inch, 6.1-inch, 5.5-inch, 4.7-inch, and 4-inch versions are generated by scaling. You &lt;em&gt;may&lt;/em&gt; still upload size-specific screenshots when you want pixel-perfect control on a given device; it just isn’t required anymore.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;iPad, required if your app runs on iPad:&lt;/strong&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Display&lt;/th&gt;
      &lt;th&gt;Portrait dimensions&lt;/th&gt;
      &lt;th&gt;Devices&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;13-inch&lt;/td&gt;
      &lt;td&gt;2064 × 2752 · 2048 × 2732&lt;/td&gt;
      &lt;td&gt;iPad Pro (M4), iPad Air (M2/M3/M4)&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The 11-inch and smaller iPad sizes scale from the 13-inch set.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mac, required if your app runs on Mac:&lt;/strong&gt; a 16:10 image at 1280 × 800, 1440 × 900, 2560 × 1600, or 2880 × 1800.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Count, format, and order:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;1 to 10&lt;/strong&gt; screenshots per localization, per display size.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;PNG or JPEG&lt;/strong&gt;, RGB, flattened (no alpha/transparency), at the exact pixel dimensions above.&lt;/li&gt;
  &lt;li&gt;Only the &lt;strong&gt;first two to three&lt;/strong&gt; appear in App Store search results without tapping in, so put your strongest screenshots first and treat the rest as extra detail.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Apple revises these as new hardware ships; the numbers above are current as of June 2026. Before any release, check them against &lt;a href=&quot;https://developer.apple.com/help/app-store-connect/reference/screenshot-specifications/&quot;&gt;Apple’s official screenshot specifications&lt;/a&gt;. The specs can’t protect you from the other half, which is content.&lt;/p&gt;

&lt;h2 id=&quot;what-233-actually-says&quot;&gt;What §2.3.3 actually says&lt;/h2&gt;

&lt;p&gt;Apple has reworded §2.3.3 a few times since 2017, but the intent has stayed the same: a screenshot represents the app a user will receive. That means the actual app in actual use, and excludes a future version, a concept, or a marketing illustration of what you wish the app did.&lt;/p&gt;

&lt;p&gt;The boundaries:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;What’s allowed:&lt;/strong&gt; Overlaid feature copy on top of a screen capture. Colored background fields around the device. Gradient or photographic backgrounds. 3D device frames. Decorative typographic emphasis. Multiple screenshots in a sequence telling a story.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;What gets rejected:&lt;/strong&gt; Fictional UI that isn’t in the app. Features that haven’t shipped yet. Pure marketing illustration with no real screen content. Screenshots whose UI was Photoshopped after capture to look prettier than the app does.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In plain language: the &lt;em&gt;content inside the device screen&lt;/em&gt; must be the real app. Everything &lt;em&gt;around&lt;/em&gt; the device frame is decorative styling and mostly up to you.&lt;/p&gt;

&lt;h2 id=&quot;the-five-rejection-patterns-ive-seen-most-often&quot;&gt;The five rejection patterns I’ve seen most often&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. The “future-build” screenshot.&lt;/strong&gt; The most common one. A marketing team shipped a previous version’s UI in the screenshot bundle, or used a Figma concept that hasn’t been built yet. The reviewer downloads the app, can’t find the feature, and rejects it. Re-render screenshots from the build you’re submitting, every time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The “concept-art” screenshot.&lt;/strong&gt; Especially common in apps with heavy graphics: games, drawing apps, AR apps. The screenshot looks more like a website hero shot than an in-app capture, and the reviewer reads it as misleading. The fix is to find a moment in the app that looks like the hero shot and capture that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. The “deleted-feature” screenshot.&lt;/strong&gt; A feature existed in version 2.4 and was removed in 2.7, but the 2.4 screenshots are still uploaded for 2.7. Re-uploading old screenshots is an easy way to inherit a rejection from your own past.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. The “in-app-purchase price mismatch.”&lt;/strong&gt; The screenshot says “$0.99, limited time” and the App Store listing says $4.99. The reviewer flags the inconsistency. Either show real IAP prices that match the listing, or leave prices out of screenshots altogether.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. The “fictional metric” screenshot.&lt;/strong&gt; Common in fitness, finance, and analytics apps. The screenshot shows “247,891 active users this month” or “+42% sleep score”, but the demo data in today’s shipping app shows different numbers. The reviewer treats this as misrepresentation.&lt;/p&gt;

&lt;h2 id=&quot;app-preview-videos-specs-and-the-same-content-rule&quot;&gt;App Preview videos: specs and the same content rule&lt;/h2&gt;

&lt;p&gt;App Preview videos have their own specifications, and §2.3.3 applies to them as well.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Up to 3&lt;/strong&gt; previews per localization, each &lt;strong&gt;15 to 30 seconds&lt;/strong&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;iPhone:&lt;/strong&gt; 886 × 1920 portrait (886 covers 6.9-inch through 6.1-inch). &lt;strong&gt;iPad:&lt;/strong&gt; 1200 × 1600.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Formats:&lt;/strong&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.mov&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.m4v&lt;/code&gt;, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.mp4&lt;/code&gt;: H.264 at roughly 10 to 12 Mbps or ProRes 422 (HQ), 30 fps, AAC audio.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The content rule is enforced strictly here. The video must be &lt;strong&gt;actual app footage captured from a device&lt;/strong&gt;. A screen-recorded mockup, an animated concept reel, or camera footage of someone holding a phone will not pass. Apple checks this closely, especially for new apps.&lt;/p&gt;

&lt;h2 id=&quot;how-to-make-your-screenshot-pipeline-233-safe&quot;&gt;How to make your screenshot pipeline §2.3.3-safe&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Capture from a build, not a design tool.&lt;/strong&gt; Use Simulator, Xcode UI tests, or manual capture from a TestFlight build to produce the raw screen content. If it didn’t come from a running build, it doesn’t belong inside the device frame.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Re-capture for every release.&lt;/strong&gt; Reusing screenshots after minor UI changes is tempting, and each time you do it you risk a rejection over a feature that disappeared without anyone noticing.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Strip IAP prices unless you’re certain.&lt;/strong&gt; If the prices are dynamic, regional, or change with promotions, leave them out of screenshots entirely and show what the features do.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;If you do show metrics, match the demo state of the shipping build.&lt;/strong&gt; Use the same fixture data your TestFlight build uses. Don’t render “247K users” if the demo state shows “1.2K.”&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Treat the device frame as cosmetics.&lt;/strong&gt; Pick whatever visual style fits your brand: 3D Metal render, flat outline, tilted angle, transparent background, or no frame at all. Reviewers don’t care about the frame, only about what’s on the screen inside it.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A capture-first tool like &lt;a href=&quot;/apps/mockly/&quot;&gt;Mockly&lt;/a&gt; complies with §2.3.3 by default because its workflow runs in the safe order: &lt;em&gt;capture the real screen first, render the device frame around it second.&lt;/em&gt; The screen content is your actual app, and the frame is a render placed around it. The reverse workflow (mock up a concept screen in Figma, drop it into a phone outline, export) is the one most likely to drift into rejection territory, because it invites you to design screens the app doesn’t have yet.&lt;/p&gt;

&lt;h2 id=&quot;tldr&quot;&gt;TL;DR&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;One iPhone size now.&lt;/strong&gt; 6.9-inch (1320 × 2868 / 1290 × 2796) or 6.5-inch (1242 × 2688); Apple scales it to smaller iPhones. iPad apps add 13-inch (2064 × 2752).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;1 to 10 screenshots&lt;/strong&gt; per localization, PNG or JPEG, flattened. The first 2 or 3 show in search, so put the best ones first.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;§2.3.3 covers the screen content and ignores the device frame.&lt;/strong&gt; Overlay text, backgrounds, and 3D frames are fine.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The screen must be the real shipping app.&lt;/strong&gt; Concept art, future-build UI, deleted features, fake metrics, and mismatched IAP prices are the common rejection paths.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;App Previews:&lt;/strong&gt; up to 3, 15 to 30 seconds, 886 × 1920 on iPhone, with the same “real footage only” rule.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Capture-first workflows pass cleanly;&lt;/strong&gt; design-first workflows tend to drift.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the surrounding workflow, see the &lt;a href=&quot;/journal/the-case-for-native-screenshot-tooling/&quot;&gt;native screenshot tooling argument&lt;/a&gt;, &lt;a href=&quot;/journal/shipping-app-store-screenshots-in-39-languages/&quot;&gt;shipping screenshots in 39 languages&lt;/a&gt;, and the rest of the &lt;a href=&quot;/for/indie-ios-developers/&quot;&gt;indie iOS developer tools&lt;/a&gt;. The specs change with each new device, while the intent of §2.3.3 has held for nearly a decade. The rejection emails keep arriving because most indie pipelines treat compliance as an afterthought.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>The 30 chess mistake motifs Chessful detects (and why each one matters)</title>
    <link href="https://lagerland-apps.github.io/journal/30-chess-mistake-motifs/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/30-chess-mistake-motifs/</id>
    <published>2026-05-13T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Most chess apps reduce &apos;why did I lose&apos; to a centipawn graph. Chessful sorts the mistake into one of about thirty specific categories, each with a name, a structural cause, and a drill that fixes it. This post is the full catalogue. Chessful users can use it as a reference, and anyone else gets a short tour of the mistakes that decide club-level games.</summary>
    <content type="html">&lt;p&gt;After the earlier post, &lt;a href=&quot;/journal/how-chessful-builds-adaptive-training/&quot;&gt;How Chessful turns a Stockfish evaluation into adaptive training&lt;/a&gt;, went up, the most common follow-up question was simple: &lt;em&gt;what are the motif categories?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That post described the pipeline and left the catalogue as a black box of “about thirty categories.” Here is the full current taxonomy, organised under the five skill dimensions Chessful tracks, with the structural cause of each motif and the drill that fixes it.&lt;/p&gt;

&lt;p&gt;The taxonomy isn’t proprietary. Most of these categories are standard chess teaching, covered in Aagaard’s &lt;em&gt;Excelling at Chess&lt;/em&gt; series, Yusupov’s nine-volume &lt;em&gt;Build Up Your Chess&lt;/em&gt; curriculum, Silman’s &lt;em&gt;How to Reassess Your Chess&lt;/em&gt;, and de la Maza’s &lt;em&gt;Rapid Chess Improvement&lt;/em&gt;. A few (repertoire drift, book-move missed, time-on-wrong-move) are things an analyser with your full game history can see and a coach reviewing one game can’t. The rest is standard improvement material under a name a club player can remember during the next game.&lt;/p&gt;

&lt;p&gt;We publish the catalogue because &lt;strong&gt;you can only argue with an algorithm if you know what it is looking for&lt;/strong&gt;. Without the list, you can’t tell whether Chessful’s classifier flagged the right thing in your game. With it, you can check.&lt;/p&gt;

&lt;h2 id=&quot;skill-dimension-1-tactics-10-motifs&quot;&gt;Skill dimension 1: Tactics (10 motifs)&lt;/h2&gt;

&lt;p&gt;In a tactical motif the mistake was a failure of calculation or pattern recognition in a forcing sequence. These are usually the easiest to act on: they drill well, you learn to spot them quickly, and they come up again in every opening.&lt;/p&gt;

&lt;h3 id=&quot;1-hung-piece&quot;&gt;1. Hung piece&lt;/h3&gt;

&lt;p&gt;The classic. You moved a piece (or left one) on a square where it can be taken for nothing, or for less than it’s worth. Drilling pattern: a piece-safety scan of the position before you commit to a move.&lt;/p&gt;

&lt;h3 id=&quot;2-missed-fork&quot;&gt;2. Missed fork&lt;/h3&gt;

&lt;p&gt;An enemy piece (often a knight) could reach a square that attacks two of your pieces at once and wins material. Drilling pattern: knight-radius blindness, meaning learning to see where an opposing knight could land next, especially around the king.&lt;/p&gt;

&lt;h3 id=&quot;3-missed-pin&quot;&gt;3. Missed pin&lt;/h3&gt;

&lt;p&gt;You moved a piece so that another piece behind it could no longer move (or would be unprotected if it did). Drilling pattern: awareness of files and diagonals around long-range pieces (bishops, rooks, queens).&lt;/p&gt;

&lt;h3 id=&quot;4-missed-skewer&quot;&gt;4. Missed skewer&lt;/h3&gt;

&lt;p&gt;A piece attacked a more valuable piece in front, forced it to move, and took the less valuable piece behind. Drilling pattern: noticing when pieces line up, particularly rooks on the back rank and queens on a shared diagonal.&lt;/p&gt;

&lt;h3 id=&quot;5-missed-discovered-attack&quot;&gt;5. Missed discovered attack&lt;/h3&gt;

&lt;p&gt;A piece moved out of the way and uncovered an attack by the piece behind it, often with check. Drilling pattern: x-ray vision through your own pieces.&lt;/p&gt;

&lt;h3 id=&quot;6-missed-double-attack&quot;&gt;6. Missed double attack&lt;/h3&gt;

&lt;p&gt;One move that attacks two separate enemy pieces or squares, not necessarily a fork. Drilling pattern: spotting two threats at once.&lt;/p&gt;

&lt;h3 id=&quot;7-missed-deflection&quot;&gt;7. Missed deflection&lt;/h3&gt;

&lt;p&gt;A piece needed to be lured off a critical defensive square, and the deflecting move was there but wasn’t played. Drilling pattern: finding which enemy piece is over-loaded (defending several squares) and the move that exploits it.&lt;/p&gt;

&lt;h3 id=&quot;8-missed-overload&quot;&gt;8. Missed overload&lt;/h3&gt;

&lt;p&gt;A defending piece had too many jobs, and a single attack forced it to choose and won material. Drilling pattern: counting attackers and defenders on every critical square before you commit.&lt;/p&gt;

&lt;h3 id=&quot;9-back-rank-threat&quot;&gt;9. Back-rank threat&lt;/h3&gt;

&lt;p&gt;Your own pieces blocked your king’s escape squares, and a back-rank mate was available but not seen (in either direction). Drilling pattern: prophylactic h-pawn pushes and recognising rook-plus-back-rank shapes.&lt;/p&gt;

&lt;h3 id=&quot;10-smothered-mate-possibility&quot;&gt;10. Smothered mate possibility&lt;/h3&gt;

&lt;p&gt;A knight on f7 / f2 (or similar) gives mate when the king’s own pieces block its escape squares. It’s less common, but when it appears it usually decides the game.&lt;/p&gt;

&lt;h2 id=&quot;skill-dimension-2-defense-5-motifs&quot;&gt;Skill dimension 2: Defense (5 motifs)&lt;/h2&gt;

&lt;p&gt;Club players train defense less than anything else. Generic puzzle apps drill attacking tactics, while failing to recognise defensive problems is what costs games in the 1200 to 1800 range.&lt;/p&gt;

&lt;h3 id=&quot;11-defender-removal-blindness&quot;&gt;11. Defender-removal blindness&lt;/h3&gt;

&lt;p&gt;The piece you just moved was the only defender of a critical square (often on the back rank, often next to the king). Drilling pattern: before any capture or trade, check whether your piece is currently defending something. This is the most common motif at club level; Chessful logs flag it more than any other category.&lt;/p&gt;

&lt;h3 id=&quot;12-king-safety-underestimate&quot;&gt;12. King-safety underestimate&lt;/h3&gt;

&lt;p&gt;You played a move that opens lines toward your king (a pawn move, a piece trade) and did nothing about the structural weakness it created. Drilling pattern: counting attackers near the king before each move.&lt;/p&gt;

&lt;h3 id=&quot;13-prophylactic-skip&quot;&gt;13. Prophylactic skip&lt;/h3&gt;

&lt;p&gt;A defensive move (often h3 / h6, or a piece retreat to a defensive square) was available and would have stopped a threat that arrived three moves later. Drilling pattern: looking for the opponent’s plan before you make your own.&lt;/p&gt;

&lt;h3 id=&quot;14-weakening-pawn-push-without-compensation&quot;&gt;14. Weakening pawn push without compensation&lt;/h3&gt;

&lt;p&gt;A pawn push (often f3 / f6 or g3 / g6) created a hole or weakened a diagonal without giving you enough activity back. Drilling pattern: pawn-structure awareness, meaning knowing which pawn moves leave permanent weaknesses.&lt;/p&gt;

&lt;h3 id=&quot;15-wrong-piece-exchanged-for-defender&quot;&gt;15. Wrong piece exchanged for defender&lt;/h3&gt;

&lt;p&gt;A trade you started removed one of your own defenders and left a critical square uncovered. It differs from defender-removal blindness because you chose the trade. Drilling pattern: counting defenders after the trade.&lt;/p&gt;

&lt;h2 id=&quot;skill-dimension-3-positional-play-5-motifs&quot;&gt;Skill dimension 3: Positional play (5 motifs)&lt;/h2&gt;

&lt;p&gt;Positional motifs take longest to drill, but the improvement lasts longest too, and it carries over from one opening to another.&lt;/p&gt;

&lt;h3 id=&quot;16-wrong-piece-traded&quot;&gt;16. Wrong piece traded&lt;/h3&gt;

&lt;p&gt;You traded a structurally important piece (a good bishop, an active knight) for a less important enemy piece. Drilling pattern: judging piece quality before any trade.&lt;/p&gt;

&lt;h3 id=&quot;17-wrong-side-castled&quot;&gt;17. Wrong side castled&lt;/h3&gt;

&lt;p&gt;You castled on one side when the pawn structure or piece placement made the other side safer. Drilling pattern: a structural check before castling.&lt;/p&gt;

&lt;h3 id=&quot;18-weak-square-allowed&quot;&gt;18. Weak square allowed&lt;/h3&gt;

&lt;p&gt;You let an enemy piece reach an outpost (often c4 / c5 / d4 / d5 / e4 / e5 / f4 / f5) where nothing could challenge it. Drilling pattern: spotting outposts before your opponent gets there.&lt;/p&gt;

&lt;h3 id=&quot;19-wrong-pawn-break&quot;&gt;19. Wrong pawn break&lt;/h3&gt;

&lt;p&gt;A pawn break (the move that resolves central tension or opens an attacking path) came too late, at the wrong moment, or in the wrong direction. Drilling pattern: learning the standard pawn break for each pawn structure.&lt;/p&gt;

&lt;h3 id=&quot;20-time-on-the-clock-on-the-wrong-move&quot;&gt;20. Time-on-the-clock-on-the-wrong-move&lt;/h3&gt;

&lt;p&gt;This one is specific to Chessful. You spent far too much clock time on a move that didn’t need it (often a forced recapture or a routine developing move) and were short of time for a critical decision later. Drilling pattern: budgeting time per move. It’s only flagged in games played with a clock.&lt;/p&gt;

&lt;h2 id=&quot;skill-dimension-4-openings-3-motifs&quot;&gt;Skill dimension 4: Openings (3 motifs)&lt;/h2&gt;

&lt;p&gt;Opening motifs depend most on the individual user, because they depend on the repertoire you actually play. Over time Chessful builds a profile of your most-played lines and flags deviations from them.&lt;/p&gt;

&lt;h3 id=&quot;21-repertoire-drift&quot;&gt;21. Repertoire drift&lt;/h3&gt;

&lt;p&gt;You left your usual opening setup in a way that lost a tempo, allowed an early exchange you normally avoid, or transposed into a structure outside your repertoire. Drilling pattern: reviewing the opening line around the point where you deviated.&lt;/p&gt;

&lt;h3 id=&quot;22-book-move-missed&quot;&gt;22. Book-move missed&lt;/h3&gt;

&lt;p&gt;A widely known book continuation was available and was the principled move. You played a reasonable-looking non-book move that gave up an advantage the book line keeps. Drilling pattern: studying the book line in that specific opening.&lt;/p&gt;

&lt;h3 id=&quot;23-transposition-into-a-bad-line&quot;&gt;23. Transposition into a bad line&lt;/h3&gt;

&lt;p&gt;Your sequence of moves transposed into a position known to be inferior, often because the move order gave up a critical defensive resource. Drilling pattern: transposition awareness within your own repertoire.&lt;/p&gt;

&lt;h2 id=&quot;skill-dimension-5-endgames-6-motifs&quot;&gt;Skill dimension 5: Endgames (6 motifs)&lt;/h2&gt;

&lt;p&gt;Endgame motifs are the most technical. Pattern recognition has to come with concrete calculation, and small mistakes here are the likeliest to turn a winning position into a draw.&lt;/p&gt;

&lt;h3 id=&quot;24-opposition-direction-error&quot;&gt;24. Opposition direction error&lt;/h3&gt;

&lt;p&gt;In a king-and-pawn endgame you took (or gave up) the opposition in the wrong direction, so the opposing king could either advance with its pawn or block yours. Drilling pattern: technique for direct, distant, and diagonal opposition.&lt;/p&gt;

&lt;h3 id=&quot;25-king-too-late&quot;&gt;25. King-too-late&lt;/h3&gt;

&lt;p&gt;Your king didn’t become active in time. It stayed on the back rank while the opposing king walked to the centre and the position simplified into a lost king-and-pawn race. Drilling pattern: recognising the moment in a middlegame when activating the king becomes the most important move.&lt;/p&gt;

&lt;h3 id=&quot;26-wrong-rook-activation&quot;&gt;26. Wrong rook activation&lt;/h3&gt;

&lt;p&gt;In a rook endgame you put your rook in a passive spot (behind your own pawn, or in front of an opposing passed pawn from the wrong side). Drilling pattern: Tarrasch’s rule, rooks behind passed pawns, both yours and the opponent’s.&lt;/p&gt;

&lt;h3 id=&quot;27-drawn-but-played-on&quot;&gt;27. Drawn-but-played-on&lt;/h3&gt;

&lt;p&gt;You turned a winning endgame into a draw with a move that simplified into a known drawn structure (often a wrong-color bishop ending, or a fortress). Drilling pattern: recognising drawn endgame structures before you simplify into them.&lt;/p&gt;

&lt;h3 id=&quot;28-wrong-color-bishop-endgame&quot;&gt;28. Wrong-color bishop endgame&lt;/h3&gt;

&lt;p&gt;You traded into an endgame where your remaining bishop is the wrong colour to control your passed pawn’s promotion square. It often comes together with drawn-but-played-on. Drilling pattern: projecting the endgame before the trade.&lt;/p&gt;

&lt;h3 id=&quot;29-technique-error-in-kp-endgame&quot;&gt;29. Technique error in K+P endgame&lt;/h3&gt;

&lt;p&gt;A known winning technique (Lucena, Philidor, square-of-the-pawn, key-square calculation) was available, and you didn’t execute it correctly. Drilling pattern: repeating the specific technique that failed.&lt;/p&gt;

&lt;h3 id=&quot;30-technique-error-in-rp-endgame&quot;&gt;30. Technique error in R+P endgame&lt;/h3&gt;

&lt;p&gt;The rook-endgame version of the K+P motif: you picked the right technique (Lucena bridge, Philidor third-rank defence, short-side defence) and executed it incorrectly. Drilling pattern: repetition of that specific rook-endgame technique.&lt;/p&gt;

&lt;h2 id=&quot;how-the-catalogue-maps-to-training&quot;&gt;How the catalogue maps to training&lt;/h2&gt;

&lt;p&gt;Each motif belongs to exactly one of the five skill buckets (the dimension it’s listed under above). When Chessful flags a motif in one of your games, it flags that skill bucket. The spaced-repetition queue draws from the flagged buckets, most recently flagged first, with Leitner-schedule intervals between repeats.&lt;/p&gt;

&lt;p&gt;The bucket layer sits between motif detection and the training queue because &lt;strong&gt;patterns generalise better within a skill dimension than across dimensions&lt;/strong&gt;. If you keep missing forks, more fork puzzles are the right fix. If you alternate between missing forks and misjudging the opposition in endgames, those are two separate failures and need separate drilling, which a generic “tactics-and-endgame practice” queue wouldn’t give you.&lt;/p&gt;

&lt;p&gt;So the skill dimensions are where spaced repetition gets scheduled, and grouping the list for display is a side effect.&lt;/p&gt;

&lt;h2 id=&quot;whats-not-in-the-catalogue-and-why&quot;&gt;What’s not in the catalogue (and why)&lt;/h2&gt;

&lt;p&gt;A few things Chessful deliberately doesn’t detect:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Time-pressure tactics.&lt;/strong&gt; A blunder with under thirty seconds on the clock is often a time-management problem and not a pattern problem. Chessful flags it as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;time-on-the-clock-on-the-wrong-move&lt;/code&gt; (motif 20) and not as a tactical failure, because drilling tactics doesn’t fix time pressure. Drilling time budgeting does.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Move-order subtleties in deeply theoretical lines.&lt;/strong&gt; If you play the Najdorf Poisoned Pawn and miss a nuance on move 20, Chessful flags it as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;repertoire drift&lt;/code&gt;, not as a positional or tactical motif. What helps there is opening study, and pattern drilling wouldn’t.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Psychological mistakes.&lt;/strong&gt; Resigning too early, accepting a draw in a winning position, playing too aggressively when ahead: Chessful doesn’t try to detect these, because engine output alone can’t reliably tell them apart from objective mistakes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We left these out on purpose. In each case motif drilling is the wrong fix, and Chessful would mislead you by pretending it wasn’t.&lt;/p&gt;

&lt;h2 id=&quot;how-the-catalogue-evolves&quot;&gt;How the catalogue evolves&lt;/h2&gt;

&lt;p&gt;The catalogue changes between app versions in two ways:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;New motifs get added&lt;/strong&gt; when a recurring mistake shows up in user games and the existing rules don’t catch it cleanly. The latest addition (v1.4) was &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;weakening pawn push without compensation&lt;/code&gt;. It used to be part of king-safety underestimate and was split out because the two need different drills.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Existing motifs occasionally get split or merged&lt;/strong&gt; when one category is doing too much work, or when two categories rarely produce different training value. We’re conservative about it and only do it when the resulting training queue would clearly differ.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every change goes in the app’s changelog with the motif name and the version. The spaced-repetition queue doesn’t reset when the taxonomy changes; flagged positions move to the closest matching motif in the new taxonomy.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;This catalogue is what Chessful is checking when it tells you “you played Nxd5; the knight was your only back-rank defender.” That sentence is what you see. Underneath, the motif label is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;defender-removal blindness&lt;/code&gt;, the bucket it flags is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Defense&lt;/code&gt;, and your next training session draws from that bucket using spaced repetition.&lt;/p&gt;

&lt;p&gt;All of it is open to inspection, which is why we published it.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://apps.apple.com/app/id6761336870&quot;&gt;Chessful is available on the App Store.&lt;/a&gt; The method behind the catalogue is in &lt;a href=&quot;/journal/how-chessful-builds-adaptive-training/&quot;&gt;How Chessful turns a Stockfish evaluation into adaptive training&lt;/a&gt;. The companion design note on the forty AI opponents is &lt;a href=&quot;/journal/forty-chess-opponents/&quot;&gt;Forty chess opponents, and none of them are me&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>The Mac already shipped with every media tool, and someone just had to wire them together</title>
    <link href="https://lagerland-apps.github.io/journal/every-media-tool-already-on-your-mac/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/every-media-tool-already-on-your-mac/</id>
    <published>2026-05-09T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">MediaKit is 133 local tools for video, audio, image, PDF, and archive work, behind a single drag-and-drop Mac interface. Every operation runs on your machine. This post makes the case for that, and for why &quot;upload your file to a random website to convert it&quot; remains one of the worst defaults on the open web in 2026.</summary>
    <content type="html">&lt;p&gt;It’s a Saturday in May. Somewhere on the open web, someone is uploading a four-gigabyte video of a child’s piano recital to a free conversion site, because the format their camera produces is the format their parent cannot open. The site will take the video, run it through a server they cannot see, log the request, possibly cache the file, certainly read the metadata, and hand back something that plays on a Windows laptop. The user will close the tab and assume it’s fine.&lt;/p&gt;

&lt;p&gt;It is not fine, and in 2026 it is also unnecessary.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/apps/mediakit/&quot;&gt;MediaKit&lt;/a&gt; is the small Mac app the studio shipped this spring on exactly this premise: every media-conversion operation a normal user needs has, for a decade, been doable locally on a Mac, and CloudConvert, Zamzar, Smallpdf, and the rest still dominate because nobody had bothered to consolidate those local primitives behind a single drag-and-drop interface.&lt;/p&gt;

&lt;p&gt;This is the Saturday essay on what MediaKit is, what it isn’t, and why “free conversion website” is one of the worst remaining defaults on the open web.&lt;/p&gt;

&lt;h2 id=&quot;what-media-tools-does-apple-already-ship-on-the-mac&quot;&gt;What media tools does Apple already ship on the Mac?&lt;/h2&gt;

&lt;p&gt;I want to be precise about this, because MediaKit’s contribution is real but limited.&lt;/p&gt;

&lt;p&gt;The actual algorithms (H.264 encoding, HEVC encoding, AAC encoding, PNG quantization, PDF compression, RAR extraction, AES-256 archive encryption, OCR, on-device speech transcription, image upscaling, background removal) all come from first-party Apple frameworks that ship with macOS:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;AVFoundation&lt;/strong&gt; handles every video and audio operation MediaKit performs, including compression, conversion, trimming, merging, and frame-accurate cuts.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;CoreImage&lt;/strong&gt; handles every image transform, color adjustment, and pixel-level filter.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;PDFKit&lt;/strong&gt; handles merge, split, redact, sign, watermark, OCR, header/footer, and vector-preserving edits.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Vision&lt;/strong&gt; handles OCR, image classification, and background removal.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Speech&lt;/strong&gt; handles on-device transcription of audio and video.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Compression&lt;/strong&gt; and &lt;strong&gt;AppleArchive&lt;/strong&gt; handle ZIP, TAR, GZIP, XZ, BZIP2, and RAR extraction, with path-traversal-safe extraction and AES-256 encryption.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of this is new or proprietary to the studio. The frameworks have been on every Mac for years, they are sandboxed and hardened-runtime-safe, and they have been optimized for Apple Silicon since the M1 launched.&lt;/p&gt;

&lt;p&gt;MediaKit wires them together: one app with one drag-and-drop surface, a menu bar item, six Shortcuts actions, and 133 distinct tools mapped against the formats and operations a normal Mac user actually wants. The alternative is five separate utilities, each with its own settings panel, license model, and update cadence.&lt;/p&gt;

&lt;p&gt;So the bet is consolidation. Nothing in MediaKit is novel, and I am going to keep saying so, because the marketing temptation to overclaim is real.&lt;/p&gt;

&lt;h2 id=&quot;why-the-cloud-converters-persist-anyway&quot;&gt;Why the cloud converters persist anyway&lt;/h2&gt;

&lt;p&gt;If the local primitives have been there for years, why does the median user still upload their video to a stranger?&lt;/p&gt;

&lt;p&gt;There are four, and they also explain the shape MediaKit had to take:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Discovery.&lt;/strong&gt; Search “convert HEIC to JPG” and the top results are conversion websites. Search “convert HEIC to JPG on Mac” and the top results are &lt;em&gt;also&lt;/em&gt; conversion websites. Apple does not market the existence of CoreImage to end users. They shouldn’t have to.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Format coverage.&lt;/strong&gt; Mac built-ins handle the common formats; the cloud converters handle the long tail: RAR v5 with encryption, AVIF, ALAC inside an unusual MKV. The user reaches for the website because the website &lt;em&gt;will&lt;/em&gt; handle whatever they throw at it. MediaKit’s goal is to cover the same long tail using Apple frameworks plus a handful of permissively-licensed local libraries, with no cloud round-trip.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;One-shot UX.&lt;/strong&gt; The website is one click: paste, drop, download. Native tools historically required you to know which app to open. The drag-and-drop unified surface in MediaKit answers this: drop any file and MediaKit picks the right tool.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Trust by exhaustion.&lt;/strong&gt; Users are tired, the website is fast and looks professional, and the privacy cost is invisible. It only becomes visible if you imagine that file being indexed somewhere, or showing up in a data-breach disclosure later.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I do not think most users &lt;em&gt;want&lt;/em&gt; to upload sensitive files to strangers. I think they have not been given a default that is just as easy not to.&lt;/p&gt;

&lt;h2 id=&quot;whats-free-and-whats-paid&quot;&gt;What’s free, and what’s paid&lt;/h2&gt;

&lt;p&gt;The free tier is five tools: Video Compress, Image Compress, Image Resize, Audio Convert, and PDF Compress. These are the operations the median Mac user actually performs: the email-attachment compress, the iPhone-photo-to-JPG, the audio rip. They stay free for good, with no nag screen, countdown, or upsell modal blocking the export.&lt;/p&gt;

&lt;p&gt;The first three days, every one of the 133 tools is unlocked, so you can find out whether the long tail matters to you before you decide. After three days, the five free tools stay free; the remaining 128 require Pro. Pro is sold monthly, yearly, or as a one-time lifetime purchase, so you can skip the subscription entirely.&lt;/p&gt;

&lt;p&gt;Pricing the free tier this way is, in the indie Mac segment, slightly unusual. Handbrake, ImageOptim, and Keka are all free. The studio’s argument is that the operations a typical user runs &lt;em&gt;most often&lt;/em&gt; should be free in MediaKit too, permanently and not as a trial extension. If you only ever compress videos and convert HEIC, MediaKit costs you nothing, and you still get a sandboxed App Store app instead of a Homebrew install of FFmpeg.&lt;/p&gt;

&lt;p&gt;The Pro tier exists for the people who run the long tail. The studio is not trying to convert free users into Pro users; they are different people.&lt;/p&gt;

&lt;h2 id=&quot;what-mediakit-does-not-do&quot;&gt;What MediaKit does not do&lt;/h2&gt;

&lt;p&gt;Some clarifications I have learned to write down:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;MediaKit is not a non-linear editor.&lt;/strong&gt; It does not replace Final Cut Pro or DaVinci Resolve. If you are cutting a film, please do not use MediaKit; the operations available are linear (compress, convert, trim, crop, merge, normalize). The studio is not going to add a timeline.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;MediaKit is not a generative AI tool.&lt;/strong&gt; Vision and Speech are recognition frameworks: OCR, background segmentation, transcription. Image upscaling is real and produces a larger pixel buffer from a smaller one, but the studio is not running diffusion models. If you need image generation, MediaKit is the wrong tool.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;MediaKit is not a cloud sync tool.&lt;/strong&gt; There is no cloud. If you want your edits accessible from another device, save them to iCloud Drive yourself, or wherever you keep your files.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;MediaKit is not a fix for the cloud-converter problem at the institutional level.&lt;/strong&gt; Universities still tell students to upload PDFs to a third-party tool because the IT department has not bothered to install anything. The studio cannot fix that from outside. But on a personal Mac, the answer is now in the App Store.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;a-note-on-the-holiday-weekend&quot;&gt;A note on the holiday weekend&lt;/h2&gt;

&lt;p&gt;For US, Canadian, Australian, and several European readers, tomorrow is Mother’s Day. There is a non-zero chance you are about to send a family video to a parent in a format they cannot open. If you find yourself reaching for a conversion website to fix it: please don’t.&lt;/p&gt;

&lt;p&gt;The file is going to ride through someone else’s data centre on the way back. It is not going to be deleted the moment you close the tab, regardless of what the privacy policy says.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/apps/mediakit/&quot;&gt;MediaKit&lt;/a&gt; is free for the operation you most likely need (Video Compress, Image Compress, Audio Convert, PDF Compress), unlocked for three days for everything else, and it never leaves the machine.&lt;/p&gt;

&lt;p&gt;The studio’s broader argument on cloud-vs-local file handling is in the &lt;a href=&quot;/journal/your-photos-shouldnt-ride-the-elevator/&quot;&gt;photos elevator essay&lt;/a&gt; from March, if you want the longer version. The shorter version is that Apple has been giving us the primitives for years and we should use them.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>The day I plan on my phone is not the day I finish at my desk</title>
    <link href="https://lagerland-apps.github.io/journal/planning-on-phone-finishing-on-desk/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/planning-on-phone-finishing-on-desk/</id>
    <published>2026-05-02T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Taskful Day shipped on the Mac this week. This short essay explains why a calm daily planner had to be a native Mac app instead of a stretched-iPhone Catalyst window, and why it&apos;s one Universal Purchase across iPhone, iPad, and Mac instead of three separate licenses.</summary>
    <content type="html">&lt;p&gt;I do not plan my day on a phone in the kitchen and then carry the plan, unchanged, to a desk for eight hours.&lt;/p&gt;

&lt;p&gt;Nobody does. The plan I make at the coffee maker has three tasks on it, and the day I’d like to have has nine. The work happens somewhere in between, and until this week my planner didn’t run on the device I do that work on.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/apps/taskful-day/&quot;&gt;Taskful Day&lt;/a&gt; shipped on the Mac on Wednesday. This Saturday essay is about why the Mac was the missing piece, and what I did and did not do to make it work.&lt;/p&gt;

&lt;h2 id=&quot;why-i-didnt-use-catalyst&quot;&gt;Why I didn’t use Catalyst&lt;/h2&gt;

&lt;p&gt;For several years Apple has made it easy to bring an iPad app to the Mac. You click a checkbox in Xcode, set a few capabilities, fix the obvious touch-target sins and ship. A lot of indie planners and to-do apps reach the Mac this way, and structurally they are an iPad window with a menu bar.&lt;/p&gt;

&lt;p&gt;Catalyst is fine for an app you open once and dismiss, like a calculator or a unit converter. It is not fine for an app you keep open in a corner of the screen for eight hours, next to Slack, your calendar and the document you’re trying to finish. The pixels look wrong, the keyboard shortcuts feel pasted on, and the window doesn’t behave like a Mac window.&lt;/p&gt;

&lt;p&gt;So Taskful Day on Mac is a SwiftUI app built for the Mac first, with AppKit underneath wherever SwiftUI doesn’t yet give a Mac app what it needs. The window resizes the way you expect, the keyboard shortcuts are real Mac shortcuts, and the menu bar is populated. Drag-and-drop works as it should on macOS, including into and out of other apps, and a menu bar item handles quick capture without opening the main window.&lt;/p&gt;

&lt;p&gt;It took longer than Catalyst would have, and I think it was the right call.&lt;/p&gt;

&lt;h2 id=&quot;one-universal-purchase-for-all-three-devices&quot;&gt;One Universal Purchase for all three devices&lt;/h2&gt;

&lt;p&gt;The other decision: Taskful Day is one Universal Purchase across iPhone, iPad, and Mac. If you bought Pro on your iPhone two months ago, the Mac app activates Pro for you the first time you sign into the same Apple ID. You do not pay again, and there is no separate Mac SKU.&lt;/p&gt;

&lt;p&gt;Many indie apps charge separately for the Mac version, and they have good reasons: the Mac app is often a lot of extra work for a smaller audience, and a per-platform price pays for it.&lt;/p&gt;

&lt;p&gt;For a planner, though, charging twice works against what the app is for. Taskful Day exists because the day you plan on one device is the day you finish on another. Charging once for the device you plan on and again for the one you work on would make the pricing contradict the product.&lt;/p&gt;

&lt;p&gt;So it’s one purchase for every device. Universal Purchase has been around since 2020, and here it made the right setup easy.&lt;/p&gt;

&lt;h2 id=&quot;sync-through-your-own-icloud&quot;&gt;Sync through your own iCloud&lt;/h2&gt;

&lt;p&gt;Sync is the other place a planner can fail without anyone noticing. The day plan you make on your phone has to reach the Mac, the focus session you ran on the Mac has to show up in the iPhone widget, and none of it should pass through someone else’s server.&lt;/p&gt;

&lt;p&gt;Taskful Day syncs through your personal iCloud account using CloudKit. The studio has no servers involved, so I can’t see your tasks, and I can’t lose them in a database because there is no database. When you delete the app on every device and sign out of iCloud, the data is gone.&lt;/p&gt;

&lt;p&gt;Most cross-platform planners work differently: you sign up for an account, your tasks live on the company’s servers, and the apps are clients. The studio doesn’t use that model anywhere in the catalogue, including here. The cost is that you cannot share a task list with a teammate through Taskful Day, because there is no shared cloud to share through. If you need that, Taskful Day is the wrong app for you, and I’d rather you used something else.&lt;/p&gt;

&lt;h2 id=&quot;what-does-now-on-mac-change-for-taskful-day&quot;&gt;What does “now on Mac” change for Taskful Day?&lt;/h2&gt;

&lt;p&gt;In practice, the Mac app changes three things.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Planning happens at the desk now.&lt;/strong&gt; The Day Clock and Energy River views, the two ways Taskful Day shows your day, work much better on a 27-inch display than a 6-inch one. You can see the whole day in one glance, and you can drag tasks across the day with a real pointing device.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Focus sessions don’t need the phone.&lt;/strong&gt; Focus Orbit runs natively on macOS. You start a session at your desk, the rest of the desktop dims, the menu bar shows the countdown, and the iPhone stays a phone instead of a timer.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;End-of-day journaling is faster on a keyboard.&lt;/strong&gt; The daily mood and reflection entry, which felt like a 60-second exercise on phone, becomes closer to two minutes of real writing on a keyboard. You write different things, so the pattern view shows you something different a month later.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The iPhone is still the device for capture: you think of something, tap, talk, and it’s filed. The iPad is still where the morning review happens. The Mac is now where the work happens, and the planner sits next to it.&lt;/p&gt;

&lt;h2 id=&quot;where-this-fits-next-to-things-ticktick-sorted&quot;&gt;Where this fits next to Things, TickTick, Sorted³&lt;/h2&gt;

&lt;p&gt;If you’re comparing:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Things 3.&lt;/strong&gt; Things is a beautiful GTD-style task manager that assumes you want a project tree that lives forever. Taskful Day isn’t GTD; it assumes you want one day at a time, and unfinished tasks roll forward without ceremony. If you live in the Areas, Projects, Tasks hierarchy, Things is the right choice.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;TickTick.&lt;/strong&gt; TickTick is a cross-platform Swiss-army knife with reminders, calendars, habit tracking and Eisenhower matrices. Taskful Day does less on purpose: it has no habit tracker, no Pomodoro as such (the focus mode is more immersive than Pomodoro), and no team features.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Sorted³.&lt;/strong&gt; Sorted is a fantastic time-blocked planner. If you want every task to have a start and an end time, Sorted is the better tool. Taskful Day’s Day Clock view does some of this, but its aim is a realistic plan you can finish, where Sorted’s is to schedule every minute.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Taskful Day is one of several good calm-design planners. As of this week it is one of the few that ships natively on iPhone, iPad, and Mac with a single purchase and iCloud as the sync layer.&lt;/p&gt;

&lt;h2 id=&quot;get-it&quot;&gt;Get it&lt;/h2&gt;

&lt;p&gt;The iPhone, iPad, and Mac apps are all available now. The core is free on every platform. Pro, which adds the focus session timer, advanced analytics, widgets, iCloud sync and unlimited follow-ups, is &lt;strong&gt;$2.99/month&lt;/strong&gt; or &lt;strong&gt;$39.99 lifetime&lt;/strong&gt;, applied across every device you sign in with.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/apps/taskful-day/&quot;&gt;Get Taskful Day&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For the studio’s view of streak-based habit apps and why I don’t ship one, the &lt;a href=&quot;/journal/streaks-are-a-debt/&quot;&gt;streak counter essay&lt;/a&gt; makes the longer argument behind that choice in this app.&lt;/p&gt;

&lt;p&gt;Next Saturday’s entry is about the other thing I shipped this season: a Mac app full of local media tools, the kind people usually upload their files to a random website to use. I expect it to be a more pointed post.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>LiftLog ships. You pick the price.</title>
    <link href="https://lagerland-apps.github.io/journal/liftlog-pay-what-you-can/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/liftlog-pay-what-you-can/</id>
    <published>2026-04-25T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">LiftLog, a design-led strength training log for iPhone, is on the App Store today. It has no subscription. After seven days free with no card on file, you decide what it&apos;s worth to you: $9.99, $19.99, $29.99, or $39.99, paid once. This post explains why.</summary>
    <content type="html">&lt;p&gt;&lt;a href=&quot;/apps/liftlog/&quot;&gt;LiftLog&lt;/a&gt; is on the App Store today.&lt;/p&gt;

&lt;p&gt;The one thing to know about it: &lt;strong&gt;there is no subscription.&lt;/strong&gt; You get seven days free with no card on file. After that, you choose a one-time tier between $9.99 and $39.99 and you own the app. Nothing auto-renews, there’s no trial trap, and a lapsed subscription can never lock you out of your training history.&lt;/p&gt;

&lt;p&gt;The rest of this post covers why I built LiftLog this way and what I’m trying to learn from it.&lt;/p&gt;

&lt;h2 id=&quot;subscription-pricing-is-a-tax-on-training-history&quot;&gt;Subscription pricing is a tax on training history&lt;/h2&gt;

&lt;p&gt;Strength training is a long-term practice. You keep showing up, week after week, year after year, and the data you build up (the weights you’ve moved, the personal records you’ve broken, the volume you’ve put your body through) gets more valuable the longer you train.&lt;/p&gt;

&lt;p&gt;Most workout-tracker apps charge a monthly subscription. Stop paying and you lose the app, and often access to your own history. I find this morally awkward. The user generated the data, and the user’s effort produced the personal records. Charging rent on someone’s own training journal is the wrong arrangement.&lt;/p&gt;

&lt;p&gt;I know the economics. Subscriptions smooth revenue, fund support and pay for ongoing development. Services like Strong, Hevy, and Fitbod have good reasons to use them, and I don’t think those teams are doing anything wrong. I wanted to find out whether another model would work for a one-person studio shipping a single, finished product.&lt;/p&gt;

&lt;p&gt;So LiftLog is one-time. You pay once, you own it.&lt;/p&gt;

&lt;h2 id=&quot;what-does-pay-what-you-can-actually-mean-here&quot;&gt;What does “pay what you can” actually mean here?&lt;/h2&gt;

&lt;p&gt;After the seven-day free trial, the app shows you four tiers:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Fair, $9.99.&lt;/strong&gt; The entry tier. If this is the most you can justify for the app, pick it, with no guilt and no asterisk.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Good, $19.99.&lt;/strong&gt; The middle. If LiftLog has earned a serious share of your training time and you expect to keep using it, this is where I think most users will land.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Generous, $29.99.&lt;/strong&gt; A step up for users who want to support the work, or who have benefited from indie software in the past and want to give back.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Patron, $39.99.&lt;/strong&gt; The top tier. Same app, no extra unlocks. It exists so people who want to back the studio at a level closer to a year of competitor subscriptions can do that openly, without a hidden option or a tip jar.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All four tiers unlock the same product. Nothing is locked behind a higher number. You choose what LiftLog is worth to you; the features are the same either way.&lt;/p&gt;

&lt;h3 id=&quot;why-four-tiers-and-not-a-slider&quot;&gt;Why four tiers and not a slider&lt;/h3&gt;

&lt;p&gt;A slider would be more flexible, but every UX paper I’ve read on charitable giving and pay-what-you-want pricing says the same thing: give people too many options and they freeze, and when they freeze, the median amount paid drops. Four tiers give people a real choice without overload.&lt;/p&gt;

&lt;p&gt;Four also creates anchoring. If the only options were $9.99 and $19.99, almost everyone would pick $9.99. With $29.99 and $39.99 visible, $19.99 reads as moderate instead of top-end, and some users will choose to pay above the median. That’s the bet.&lt;/p&gt;

&lt;p&gt;The labels matter too. Naming the tiers &lt;em&gt;Fair / Good / Generous / Patron&lt;/em&gt; (and not &lt;em&gt;Basic / Standard / Plus / Pro&lt;/em&gt;) makes clear that more money doesn’t buy more app. It buys the studio more runway, and I want the labels to say so plainly.&lt;/p&gt;

&lt;h2 id=&quot;what-this-is-not&quot;&gt;What this is not&lt;/h2&gt;

&lt;p&gt;A few clarifications, because two friends have already asked:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;It’s not freeware.&lt;/strong&gt; The seven-day trial is generous, needs no card and doesn’t nag, but after that the app does ask you to choose a tier. I’m not Strava-ing my way into a freemium grind. The trial is real and so is the purchase.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;It’s not a stunt.&lt;/strong&gt; This isn’t a one-week marketing experiment. Pay-what-you-can is the app’s pricing model. If it doesn’t work, I’ll learn from that and write about it openly. If it does work, it stays.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;It doesn’t scale to everyone.&lt;/strong&gt; It works for a one-person studio shipping a finished, focused product. It almost certainly does not work for a SaaS company with ongoing infrastructure costs and a 50-person team. I’m only arguing that it has a place where it fits, and subscriptions can keep the rest.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;why-liftlog-and-gymlogger-x&quot;&gt;Why LiftLog &lt;em&gt;and&lt;/em&gt; GymLogger X&lt;/h2&gt;

&lt;p&gt;Lagerland Apps already has a strength training app: &lt;a href=&quot;/apps/gymlogger-x/&quot;&gt;GymLogger X&lt;/a&gt;. It has an Apple Watch app for logging sets from the wrist, generated programs and plateau detection, and costs $39.99 lifetime or $17.99/year. That app is staying. People who want a fast logger they can use from Apple Watch should buy GymLogger X; it’s the better tool for that job.&lt;/p&gt;

&lt;p&gt;LiftLog is a different bet:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Design-led, iPhone-first.&lt;/strong&gt; Tabular numerics, a custom haptic numeric keypad during sets, a restrained navy palette, and &lt;a href=&quot;/journal/choosing-a-strength-program-you-will-finish/&quot;&gt;programs&lt;/a&gt; you build yourself, with supersets and giant sets. It’s for lifters who care how their tools feel as well as what they do.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;A pricing experiment.&lt;/strong&gt; GymLogger X is the conventional answer (lifetime plus optional annual). LiftLog is the contrarian one (pay what you can, once). I want both in the catalogue so I can learn from both.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you can’t decide, it comes down to this. To log from Apple Watch, get GymLogger X. If you live on iPhone and want polish, get LiftLog. To support an indie studio’s pricing experiment, get LiftLog at the Patron tier. Any of these is a fine choice.&lt;/p&gt;

&lt;h2 id=&quot;what-ill-be-watching&quot;&gt;What I’ll be watching&lt;/h2&gt;

&lt;p&gt;I honestly don’t know how this will turn out. The questions I want answered:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;What’s the median tier choice?&lt;/strong&gt; I expect $19.99 (Good). If it’s $9.99 (Fair) by a wide margin, the anchoring isn’t working and I need to rethink the labels or the tier ladder.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;What’s the conversion rate from trial to paid tier?&lt;/strong&gt; Industry benchmarks for paid trials with no card up front sit around 5 to 15%. Dropping the card requirement reduces friction, but it also drops the auto-renew lock-in behind a lot of “subscription” revenue.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Do Patrons cluster geographically or demographically?&lt;/strong&gt; I don’t track users individually, but the App Store gives me country-level rollups and tier-level revenue. If a lot of Patron purchases come from regions where $39.99 is a serious amount of money, that changes how I think about the model.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Do reviews mention the pricing?&lt;/strong&gt; This is the qualitative signal I care about most. If users find the tier ladder respectful and unusual, the model is working. If it feels gimmicky or guilt-trippy, it isn’t, and I’ll write a follow-up explaining what I changed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’ll publish a follow-up here in three to six months with whatever the data says, including the bad numbers if there are any.&lt;/p&gt;

&lt;h2 id=&quot;try-it-free&quot;&gt;Try it free&lt;/h2&gt;

&lt;p&gt;If you train, &lt;a href=&quot;/apps/liftlog/&quot;&gt;download LiftLog&lt;/a&gt;. You get seven days of full access with no card. After that, pick a tier or don’t, and if you don’t, we part on good terms.&lt;/p&gt;

&lt;p&gt;If pay-what-you-can pricing isn’t for you, &lt;a href=&quot;/apps/gymlogger-x/&quot;&gt;GymLogger X&lt;/a&gt; costs $39.99 lifetime. It comes from the same studio with the same privacy principles and a different pricing model.&lt;/p&gt;

&lt;p&gt;Either way, your training history stays on your device, with no third-party tracking, no advertising SDKs and no required account. The app is small, the studio is one person, and those principles stay.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;a href=&quot;https://apps.apple.com/app/id6760043411&quot;&gt;LiftLog is available on the App Store.&lt;/a&gt; It’s free for seven days with no card required. After the trial you choose a one-time price: $9.99, $19.99, $29.99, or $39.99.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>A glanceable dashboard for App Store revenue, on the iPhone</title>
    <link href="https://lagerland-apps.github.io/journal/read-only-revenue-on-the-iphone/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/read-only-revenue-on-the-iphone/</id>
    <published>2026-04-18T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Your accountant doesn&apos;t need write access to App Store Connect, and neither does your designer, your spouse or your co-founder. Nobody in your weekly bookkeeping needs to be able to change your app&apos;s metadata to know how it&apos;s selling. AppMeta Pulse started as my answer to that. It turned out narrower: a quick revenue check for the account owner, on their own devices.</summary>
    <content type="html">&lt;p&gt;&lt;em&gt;Updated September 22, 2026: an earlier version of this post described shareable access tokens, a strictly read-only design and no App Store analytics. AppMeta Pulse never shipped token sharing, can send replies to customer reviews, and reads App Store impressions and page views. The post is corrected below. For current plans and prices, see the &lt;a href=&quot;/apps/appmeta-pulse/&quot;&gt;AppMeta Pulse page&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Updated October 25, 2026: this post also described a free tier with one app and 30 days of history. Pulse never had one. The free download opens a demo on sample data, and everything else needs a subscription or the lifetime unlock. The widget description is corrected too.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A small post for the third Saturday in April. Tax week is just behind us in the US, the indie iOS calendar is in the lull between Q1 and WWDC, and most studios are reconciling their books.&lt;/p&gt;

&lt;p&gt;This one’s about &lt;a href=&quot;/apps/appmeta-pulse/&quot;&gt;AppMeta Pulse&lt;/a&gt;, the iPhone app this studio ships for that moment. It is the smallest, simplest tool in the catalogue, and I am asked surprisingly often why it exists.&lt;/p&gt;

&lt;h2 id=&quot;the-setup-problem&quot;&gt;The setup problem&lt;/h2&gt;

&lt;p&gt;Two months ago &lt;a href=&quot;/journal/native-mac-client-for-app-store-connect/&quot;&gt;I wrote&lt;/a&gt; about AppMeta, the native Mac client for the &lt;em&gt;write&lt;/em&gt; side of App Store Connect, where you edit metadata, respond to reviews and submit versions. AppMeta Pulse is the &lt;em&gt;monitoring&lt;/em&gt; counterpart. It looks at App Store revenue and not much else.&lt;/p&gt;

&lt;p&gt;There are two apps because of a permissions problem most indies hit eventually.&lt;/p&gt;

&lt;p&gt;App Store Connect has one monolithic role model: either someone has access to your developer account, or they don’t. Sub-roles exist (Admin, Developer, Marketing and so on), but they are coarse. Marketing can edit metadata and Finance can read sales reports, but nobody can have &lt;em&gt;just&lt;/em&gt; “read-only revenue access without seeing build artefacts or being able to respond to reviews.”&lt;/p&gt;

&lt;p&gt;So if you want your accountant to see your revenue, you have to give them an App Store Connect account, configure their role, accept that they can see things you’d rather they didn’t, and trust them to log in to a developer web tool every time they want to check.&lt;/p&gt;

&lt;p&gt;In practice most indies send a screenshot of their numbers over Slack or iMessage. That works for a one-off request and is terrible for any regular reporting.&lt;/p&gt;

&lt;p&gt;AppMeta Pulse was first pitched as the answer. It turned out narrower, a fast check for the account owner (see the correction below).&lt;/p&gt;

&lt;h2 id=&quot;what-does-glanceable-revenue-look-like&quot;&gt;What does glanceable revenue look like?&lt;/h2&gt;

&lt;p&gt;AppMeta Pulse bets that the question people ask most, &lt;em&gt;“how is the app selling this week?”&lt;/em&gt;, deserves its own glanceable tool, separate from the editorial side where you change pricing or push a new version.&lt;/p&gt;

&lt;p&gt;The app sits on top of the App Store Connect API and reads your sales, subscription and analytics reports. It shows:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Daily, weekly and monthly revenue per app and across the portfolio.&lt;/li&gt;
  &lt;li&gt;Subscription health: trials, conversions, churn, cancellations.&lt;/li&gt;
  &lt;li&gt;Country-level revenue rollups.&lt;/li&gt;
  &lt;li&gt;Comparison views: this week against last week, this month against last month.&lt;/li&gt;
  &lt;li&gt;Per-app vs. portfolio splits.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Apart from replies to customer reviews, which arrived at the end of April 2026, nothing it shows can be edited. There is no metadata editing, build management or submission, and it is built so that it cannot do those things.&lt;/p&gt;

&lt;h2 id=&quot;why-the-iphone&quot;&gt;Why the iPhone&lt;/h2&gt;

&lt;p&gt;The form factor is iPhone, and the design is meant to be read at a glance.&lt;/p&gt;

&lt;p&gt;AppMeta does the desk work on the Mac: multi-locale metadata editing, keyword analysis, review replies. AppMeta Pulse does the &lt;em&gt;check-in&lt;/em&gt; on the phone, over the morning coffee, in the weekly meeting with a co-founder or at the quarterly review with the accountant.&lt;/p&gt;

&lt;p&gt;The use case I designed for: an indie developer in a coffee shop picks up the phone, taps Pulse, sees the last seven days’ proceeds against the seven before, and decides whether to pay attention or get on with the day. That should take three seconds, and it does.&lt;/p&gt;

&lt;p&gt;The widget is, predictably, what I look at most. The small Pulse widget shows one figure, its label and how fresh the data is; the medium one adds a sparkline. The 7-Day Dashboard widget shows proceeds, units and new subscriptions, each with its change from the previous seven days, because those are the numbers worth seeing at a glance.&lt;/p&gt;

&lt;h2 id=&quot;what-about-sharing&quot;&gt;What about sharing?&lt;/h2&gt;

&lt;p&gt;This post originally claimed a use case for AppMeta Pulse that it doesn’t cover: &lt;em&gt;sharing read-only access without granting write access&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;A co-founder, a designer on a profit share or an accountant doing quarterly bookkeeping needs to see the numbers, and none of them needs to be able to change your app’s pricing.&lt;/p&gt;

&lt;p&gt;Pulse doesn’t solve this. It has no shared access tokens and no way to give another person access to your account’s data, though you can export a CSV of a period’s sales and send it yourself. The clean way to give someone ongoing read access is still an App Store Connect account with a limited role.&lt;/p&gt;

&lt;h2 id=&quot;the-pricing-structure&quot;&gt;The pricing structure&lt;/h2&gt;

&lt;p&gt;Pulse is free to download, and the free download runs a demo on sample data so you can see what it does. Your own numbers, the portfolio view and the widgets need Pro. At the time of writing, Pro was $0.99/month, $8.99/year, or $17.99 lifetime; the App Store now lists $0.99/month, $1.99/year, or $2.99 lifetime.&lt;/p&gt;

&lt;p&gt;The price is low on purpose. A studio doesn’t use this tool for hours a day; it checks it briefly and relies on it. Pricing it like flagship productivity software would misjudge its place in an indie’s toolkit. A one-time lifetime price puts it in the buy-it-and-forget-it tier, which suits what it does.&lt;/p&gt;

&lt;h2 id=&quot;what-it-doesnt-do&quot;&gt;What it doesn’t do&lt;/h2&gt;

&lt;p&gt;AppMeta Pulse is not a financial-planning tool. It does not project revenue, model scenarios, or replace your accountant. It does no tax calculations, and it doesn’t read Payments and Financial Reports; for when Apple’s money actually arrives, see &lt;a href=&quot;/journal/when-does-apple-pay-developers/&quot;&gt;when Apple pays developers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Nor is it a full marketing-analytics tool. From App Store Connect’s analytics reports it uses only App Store impressions and product page views (it keeps a copy of the downloaded report).&lt;/p&gt;

&lt;p&gt;Pulse does one thing: it shows your App Store revenue at a glance, on your phone.&lt;/p&gt;

&lt;h2 id=&quot;a-small-note-on-the-catalogue&quot;&gt;A small note on the catalogue&lt;/h2&gt;

&lt;p&gt;By my count this is the third post this quarter about a tool for indie iOS developers. It’s also the last for a while. I want to get back to the consumer apps that make up most of the catalogue, and the next few weekends will probably go to them.&lt;/p&gt;

&lt;p&gt;If you’re an indie who read this far and you keep opening App Store Connect just to see how yesterday went, &lt;a href=&quot;/apps/appmeta-pulse/&quot;&gt;AppMeta Pulse&lt;/a&gt; is a small pay-once tool that answers that faster. Spring is the season of clean books.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>TheWait is now Soon. Why we rebuilt and rebranded</title>
    <link href="https://lagerland-apps.github.io/journal/soon-rebrand/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/soon-rebrand/</id>
    <published>2026-04-13T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">After a year of slow growth, TheWait has been fully rebuilt and relaunched as Soon. This post covers why the old name had to go, what changed under the hood, and what stays the same for existing users.</summary>
    <content type="html">&lt;p&gt;TheWait started as a simple countdown app. You pinned an event and watched the days tick down, and that was it. Over a year it grew widgets, themes, calendar sync, and photo backgrounds. The name, &lt;em&gt;TheWait&lt;/em&gt;, kept holding it back.&lt;/p&gt;

&lt;p&gt;In April 2026 I rebuilt the app from scratch and rebranded it as &lt;strong&gt;&lt;a href=&quot;/apps/soon/&quot;&gt;Soon.&lt;/a&gt;&lt;/strong&gt;, with a new name, a new icon, and a new home.&lt;/p&gt;

&lt;h2 id=&quot;why-rename-thewait-to-soon&quot;&gt;Why rename TheWait to Soon.?&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;TheWait&lt;/em&gt; describes the app literally. You wait, and the app counts down.&lt;/p&gt;

&lt;p&gt;That framing gets the feeling wrong. People use countdown apps because they’re looking forward to something. Waiting is passive and carries delay, patience, and endurance with it. Anticipation is active: you enjoy the thing a little before it arrives. When you’re counting down to a trip, a wedding, a birth, or a milestone, part of you is already there.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Soon.&lt;/em&gt; says that better. The period at the end is deliberate, because it makes the name a full sentence: the thing you’re looking forward to isn’t far off.&lt;/p&gt;

&lt;h2 id=&quot;what-changed-under-the-hood&quot;&gt;What changed under the hood&lt;/h2&gt;

&lt;p&gt;The whole app was rebuilt from scratch. New additions include:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Plan Mode.&lt;/strong&gt; Every countdown now comes with a smart timeline and checklist tailored to the event type. Trips get packing lists and transport reminders, and weddings get their own schedule. The app knows what a birthday, wedding, or graduation typically needs and assembles the prep for you, so you don’t have to write the checklist yourself.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;StandBy widgets.&lt;/strong&gt; Every iOS widget size and style: Home Screen, Lock Screen, StandBy, ring, minimal, and timeline. The event you’re most looking forward to can sit on every screen you already use.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Natural language search.&lt;/strong&gt; Type &lt;em&gt;“trips in July”&lt;/em&gt;, &lt;em&gt;“birthdays this month”&lt;/em&gt;, or &lt;em&gt;“anniversaries in 2027”&lt;/em&gt; and Soon. understands what you mean.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Memories that return.&lt;/strong&gt; A countdown that ends becomes a memory, and Soon. brings it back on every anniversary.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;iOS Calendar sync.&lt;/strong&gt; Any iOS Calendar event can become a countdown with a single tap.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;39 languages.&lt;/strong&gt; Full localization including Japanese, Chinese, Arabic, Hebrew, Korean, and every major European language.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;what-stayed-the-same&quot;&gt;What stayed the same&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Private by default.&lt;/strong&gt; Soon. has no ads, tracking, or account. Your events stay on your device. Weather requests use approximate location or a place name only, never precise location.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;A one-time purchase option.&lt;/strong&gt; Premium is $12.99 lifetime (or $1.99/month, or $9.99/year if you prefer) with a 7-day free trial. Nothing is charged automatically without your consent.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Built by one person.&lt;/strong&gt; Same developer, same catalogue, same principles. Soon. is part of the &lt;a href=&quot;/lagerland-apps/&quot;&gt;Lagerland Apps&lt;/a&gt; family of privacy-first tools.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;what-existing-thewait-users-need-to-know&quot;&gt;What existing TheWait users need to know&lt;/h2&gt;

&lt;p&gt;If you used TheWait, &lt;strong&gt;everything carries over.&lt;/strong&gt; Your events, themes, and data migrate automatically. You’ll see the new name, the new icon, and Plan Mode, and you get every new feature without paying for a second app. The upgrade is free.&lt;/p&gt;

&lt;h2 id=&quot;why-indie-studios-should-rename-when-it-matters&quot;&gt;Why indie studios should rename when it matters&lt;/h2&gt;

&lt;p&gt;Renaming an app is frightening. App Store rankings reset, existing users get confused, and some coverage stays attached to the old name. I resisted doing it for a year.&lt;/p&gt;

&lt;p&gt;A wrong name costs you every day, though. Everyone who sees the app sees the wrong framing, every conversation starts with an explanation, and every review mentions how odd the name is. Eventually the cost of keeping it is higher than the cost of changing it, and most of the cost of changing it is nerve.&lt;/p&gt;

&lt;p&gt;For a countdown app, where the whole point is moments worth waiting for, &lt;em&gt;Soon.&lt;/em&gt; is a better name than &lt;em&gt;TheWait&lt;/em&gt;. It was worth the pain.&lt;/p&gt;

&lt;p&gt;If you’re building something and the name is slightly wrong, take this as permission to change it.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;a href=&quot;https://apps.apple.com/app/id6757280643&quot;&gt;Soon. is available on the App Store.&lt;/a&gt; Free with 5 events forever, or Premium for unlimited events, weather intelligence, daily notes, recurring events, and event notifications.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>How to find a random Wikipedia article that is worth reading</title>
    <link href="https://lagerland-apps.github.io/journal/how-to-find-interesting-wikipedia-articles/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/how-to-find-interesting-wikipedia-articles/</id>
    <published>2026-04-11T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Wikipedia&apos;s Random article link draws from more than seven million articles, and only about one in a thousand of them is a featured article. Here is every route the site itself provides to something worth reading, how random each one really is, and the address that makes Random land only on reviewed articles.</summary>
    <content type="html">&lt;p&gt;The Random article link in Wikipedia’s sidebar does exactly what it says, and that is its limit. English Wikipedia has more than seven million articles. About 7,000 of them are featured articles, the grade the community gives its best writing: roughly one in a thousand. Pressing Random is a good way to meet the encyclopedia and a slow way to find its best pages.&lt;/p&gt;

&lt;p&gt;Wikipedia has better-aimed routes built in, ranging from fully random to hand-picked, and they work well in combination.&lt;/p&gt;

&lt;h2 id=&quot;every-built-in-way-to-find-something-to-read&quot;&gt;Every built-in way to find something to read&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Route&lt;/th&gt;
      &lt;th&gt;Where to find it&lt;/th&gt;
      &lt;th&gt;What you get&lt;/th&gt;
      &lt;th&gt;How it is chosen&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Random article&lt;/td&gt;
      &lt;td&gt;Sidebar link, or Special:Random&lt;/td&gt;
      &lt;td&gt;Any article&lt;/td&gt;
      &lt;td&gt;A random number matched against an index (below)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Random featured article&lt;/td&gt;
      &lt;td&gt;Special:RandomInCategory/Featured_articles&lt;/td&gt;
      &lt;td&gt;One of about 7,000 featured articles&lt;/td&gt;
      &lt;td&gt;Random within the category&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Random good article&lt;/td&gt;
      &lt;td&gt;Special:RandomInCategory/Good_articles&lt;/td&gt;
      &lt;td&gt;One of more than 40,000 good articles&lt;/td&gt;
      &lt;td&gt;Random within the category&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Today’s featured article&lt;/td&gt;
      &lt;td&gt;Main Page&lt;/td&gt;
      &lt;td&gt;One featured article a day&lt;/td&gt;
      &lt;td&gt;Scheduled by editors&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Did you know&lt;/td&gt;
      &lt;td&gt;Main Page&lt;/td&gt;
      &lt;td&gt;One-line hooks to articles that are new, newly expanded or newly promoted&lt;/td&gt;
      &lt;td&gt;Nominated and reviewed; usually one set a day&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;On this day&lt;/td&gt;
      &lt;td&gt;Main Page&lt;/td&gt;
      &lt;td&gt;Anniversaries for today’s date&lt;/td&gt;
      &lt;td&gt;Picked from a queue; quality and topic mix count&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Unusual articles&lt;/td&gt;
      &lt;td&gt;Wikipedia:Unusual articles&lt;/td&gt;
      &lt;td&gt;A long list of odd but verifiable articles, grouped by subject&lt;/td&gt;
      &lt;td&gt;Collected by editors&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Vital articles&lt;/td&gt;
      &lt;td&gt;Wikipedia:Vital articles&lt;/td&gt;
      &lt;td&gt;The topics editors think most deserve a strong article, in levels of 10 to 50,000&lt;/td&gt;
      &lt;td&gt;Agreed by editors&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Random article has a keyboard shortcut: Alt+Shift+X in Firefox, Alt+X in Chrome and Edge, as Wikipedia’s &lt;a href=&quot;https://en.wikipedia.org/wiki/Wikipedia:Random&quot;&gt;Random help page&lt;/a&gt; lists them. Special:Random also works in other language editions; on German Wikipedia it redirects to Spezial:Zufällige Seite.&lt;/p&gt;

&lt;h2 id=&quot;how-random-is-the-random-article-link&quot;&gt;How random is the Random article link?&lt;/h2&gt;

&lt;p&gt;Random enough to browse, not random enough to sample. Wikipedia’s &lt;a href=&quot;https://en.wikipedia.org/wiki/Wikipedia:FAQ/Technical&quot;&gt;technical FAQ&lt;/a&gt; explains the mechanism. Every page is given a random index, a number between 0 and 1. Special:Random draws its own random number and returns the next article whose index is higher. An article that sits just after a wide gap between indexes gets picked more often than one close behind its neighbour, so every article’s odds differ slightly, and the differences are themselves random. The FAQ’s verdict: good enough for a small sample.&lt;/p&gt;

&lt;p&gt;The pool is the main namespace: every article, long or short, reviewed or not. Run the counts from Wikipedia’s own pages and a random click lands like this:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Kind of article&lt;/th&gt;
      &lt;th&gt;How many (English Wikipedia)&lt;/th&gt;
      &lt;th&gt;Roughly one click in&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Featured article&lt;/td&gt;
      &lt;td&gt;about 7,000&lt;/td&gt;
      &lt;td&gt;1,000&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Good article&lt;/td&gt;
      &lt;td&gt;more than 40,000&lt;/td&gt;
      &lt;td&gt;160&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Any article&lt;/td&gt;
      &lt;td&gt;more than 7 million&lt;/td&gt;
      &lt;td&gt;1&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Counts as &lt;a href=&quot;https://en.wikipedia.org/wiki/Wikipedia:Featured_articles&quot;&gt;Wikipedia:Featured articles&lt;/a&gt; and &lt;a href=&quot;https://en.wikipedia.org/wiki/Wikipedia:Good_articles&quot;&gt;Wikipedia:Good articles&lt;/a&gt; gave them in April 2026. Both move every week, so check those pages for live figures.&lt;/p&gt;

&lt;p&gt;More than 99 clicks in 100 land on an article that is neither featured nor good. Plenty of those are excellent and simply unreviewed, but if you want the reviewed ones, there is a better button.&lt;/p&gt;

&lt;h2 id=&quot;how-to-aim-the-randomness&quot;&gt;How to aim the randomness&lt;/h2&gt;

&lt;p&gt;Special:RandomInCategory takes a category name and returns a random page from that category (&lt;a href=&quot;https://www.mediawiki.org/wiki/Help:RandomInCategory&quot;&gt;MediaWiki help&lt;/a&gt;). Wikipedia files every featured and good article in a maintenance category, which turns it into a quality filter:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;A random featured article:&lt;/strong&gt; &lt;a href=&quot;https://en.wikipedia.org/wiki/Special:RandomInCategory/Featured_articles&quot;&gt;Special:RandomInCategory/Featured_articles&lt;/a&gt;. Before they are listed, featured articles are reviewed as featured article candidates for accuracy, neutrality, completeness and style. On the desktop site they carry a small bronze star at the top right.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;A random good article:&lt;/strong&gt; &lt;a href=&quot;https://en.wikipedia.org/wiki/Special:RandomInCategory/Good_articles&quot;&gt;Special:RandomInCategory/Good_articles&lt;/a&gt;. Good articles meet a core set of editorial standards. They need not be as comprehensive as featured articles, but they should not omit any major facet of the subject. They carry a green plus icon.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bookmark those two addresses and you have Random buttons that only land on reviewed articles. The address works with other categories too: put a different category name after the slash.&lt;/p&gt;

&lt;h2 id=&quot;the-hand-picked-routes&quot;&gt;The hand-picked routes&lt;/h2&gt;

&lt;p&gt;The Main Page is the other way in. Each of its sections has its own selection rules.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Today’s featured article&lt;/strong&gt; is one featured article a day, so it clears the same bar as the random featured link.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Did you know&lt;/strong&gt; is where new writing surfaces. An article qualifies if it was created, expanded fivefold or promoted to good article in the seven days before its nomination, and it needs at least 1,500 characters of original prose (&lt;a href=&quot;https://en.wikipedia.org/wiki/Wikipedia:Did_you_know&quot;&gt;the rules&lt;/a&gt;). Each entry is a one-sentence hook linking to the article, and the Main Page normally runs one new set a day.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On this day&lt;/strong&gt; draws on &lt;a href=&quot;https://en.wikipedia.org/wiki/Wikipedia:Selected_anniversaries&quot;&gt;Selected anniversaries&lt;/a&gt;, a queue of historical events, holidays and observances for each date. Importance is not the only test: editors also weigh article quality and the mix of topics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Wikipedia:Unusual_articles&quot;&gt;Unusual articles&lt;/a&gt;&lt;/strong&gt; is a long list, kept by editors, of articles that are verifiable and worth having but odd or whimsical. Its sections run from places and infrastructure to food, folklore and death. It is the nearest thing Wikipedia has to a curated collection of the strange.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Wikipedia:Vital_articles&quot;&gt;Vital articles&lt;/a&gt;&lt;/strong&gt; works the other way round. It lists the subjects editors think most deserve a high-quality article, in five levels from the 10 most vital up to 50,000, which makes it a reading list for the central topics rather than the edges.&lt;/p&gt;

&lt;h2 id=&quot;combining-the-routes&quot;&gt;Combining the routes&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Five spare minutes:&lt;/strong&gt; press Random a few times and stop at the first article you want to finish.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Wanting a sure thing:&lt;/strong&gt; use the featured or good article links above.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Once a day:&lt;/strong&gt; read the Did you know hooks and On this day, which change daily.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;When something grabs you:&lt;/strong&gt; follow the categories at the bottom of the article. Each one is a shelf of neighbouring subjects, and any of them can go after the slash in RandomInCategory.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;where-wanderwiki-fits&quot;&gt;Where WanderWiki fits&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/apps/wanderwiki/&quot;&gt;WanderWiki&lt;/a&gt; puts three of these routes into a card deck on iPhone. &lt;strong&gt;Random&lt;/strong&gt; asks Wikipedia’s REST API for a random article, the API’s version of the Random article link, so almost anything in the encyclopedia can come up; the app skips disambiguation pages, lists, and stubs too short to summarise. &lt;strong&gt;For You&lt;/strong&gt; draws from topics you choose, which narrows the draw the way a category does, without watching what you linger on. &lt;strong&gt;Today in History&lt;/strong&gt; shows what happened on today’s date. Swipe to the next card, or open one to read the full article reformatted for the phone, and save the ones you want to keep.&lt;/p&gt;

&lt;p&gt;There is no account and no advertising. The &lt;a href=&quot;/apps/wanderwiki/privacy/&quot;&gt;privacy page&lt;/a&gt; sets out that saved articles and interests are stored on the device and that articles come from Wikipedia’s public APIs. Why it is a deck you put down rather than a feed you scroll is the subject of &lt;a href=&quot;/journal/reading-without-a-feed/&quot;&gt;an earlier post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The app doesn.t replace the website. If you specifically want a random featured article, the RandomInCategory address above is the most direct route.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>How to organise your bills each month: a bill calendar that matches your paydays</title>
    <link href="https://lagerland-apps.github.io/journal/how-to-organize-bills-each-month/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/how-to-organize-bills-each-month/</id>
    <published>2026-04-04T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">A list of bills tells you what you owe. It does not tell you which paycheck pays for what, and that is the question behind every short week. This post walks through the bill-calendar method the CFPB recommends, a worked example on a real 2026 pay schedule, and the formula that evens out biweekly pay.</summary>
    <content type="html">&lt;p&gt;A list of bills answers &lt;em&gt;what do I owe this month&lt;/em&gt;. The question that produces a short week is a different one: &lt;em&gt;which paycheck is paying for which bill&lt;/em&gt;. A month can balance on paper, with income comfortably above bills, and still put $1,690 of bills on one paycheck and $330 on the next, because the rent, the car loan and the insurance all land in the same fortnight.&lt;/p&gt;

&lt;p&gt;A bill calendar answers the second question. The Consumer Financial Protection Bureau publishes a printable &lt;a href=&quot;https://files.consumerfinance.gov/f/documents/cfpb_your-money-your-goals_bill_calendar_tool_2018-11_ADA.pdf&quot;&gt;bill calendar tool&lt;/a&gt; in its &lt;em&gt;Your Money, Your Goals&lt;/em&gt; toolkit, and the method works even if you never print it.&lt;/p&gt;

&lt;h2 id=&quot;the-bill-calendar-method-step-by-step&quot;&gt;The bill calendar method, step by step&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Step&lt;/th&gt;
      &lt;th&gt;What to do&lt;/th&gt;
      &lt;th&gt;The rule that makes it work&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;1. List every bill&lt;/td&gt;
      &lt;td&gt;Rent, utilities, loans, insurance, phone, subscriptions&lt;/td&gt;
      &lt;td&gt;Include autopays; they still need cash in the account&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2. Write the pay-by date&lt;/td&gt;
      &lt;td&gt;The day the money has to leave your account, not the due date&lt;/td&gt;
      &lt;td&gt;CFPB: 2 to 3 days early for online or in-person payments, at least 7 days early by mail&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;3. Add your paydays&lt;/td&gt;
      &lt;td&gt;Every date money arrives, with the amount&lt;/td&gt;
      &lt;td&gt;Use that month’s real dates, not “twice a month”&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;4. Total each pay period&lt;/td&gt;
      &lt;td&gt;Add the bills whose pay-by date falls between one payday and the next&lt;/td&gt;
      &lt;td&gt;Compare each total with the paycheck that has to cover it&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;5. Fix the heavy period&lt;/td&gt;
      &lt;td&gt;Ask to move a due date, or use a bills account&lt;/td&gt;
      &lt;td&gt;The CFPB tool suggests asking to move due dates when a week’s bills outrun its income&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;6. Recheck monthly&lt;/td&gt;
      &lt;td&gt;Look at next month before it starts&lt;/td&gt;
      &lt;td&gt;Biweekly paydays move, so April’s calendar can fail in May&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Step 2 does most of the work. The CFPB’s tool is plain about the cost of treating the due date as the target: pay even a few days late and you will likely be charged a fee, and you risk a negative entry in your credit record.&lt;/p&gt;

&lt;h2 id=&quot;why-biweekly-pay-breaks-a-monthly-calendar&quot;&gt;Why biweekly pay breaks a monthly calendar&lt;/h2&gt;

&lt;p&gt;Biweekly is the most common pay schedule in the US. In February 2023, 43.0% of private establishments paid every two weeks, according to the &lt;a href=&quot;https://www.bls.gov/ces/publications/length-pay-period.htm&quot;&gt;Bureau of Labor Statistics&lt;/a&gt;. It is also the schedule that fits a monthly calendar worst, because 14 days does not divide into a month. Your paydays land two or three days earlier in the month each month, and twice a year a month gets three of them.&lt;/p&gt;

&lt;p&gt;For a worked example, take someone paid every other Friday, with a payday on April 3, 2026, and nine monthly bills totalling $2,080: rent $1,200 on the 1st, car loan $310 on the 6th, phone $55 on the 9th, car insurance $125 on the 12th, internet $60 on the 15th, electricity $90 on the 20th, student loan $160 on the 25th, two streaming services $36 on the 27th, gym $44 on the 28th.&lt;/p&gt;

&lt;p&gt;With each pay-by date set three days before the due date, this is what each paycheck has to cover:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Payday&lt;/th&gt;
      &lt;th&gt;Bills whose pay-by date falls before the next payday&lt;/th&gt;
      &lt;th&gt;Total&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Fri Apr 3&lt;/td&gt;
      &lt;td&gt;Car loan, phone, car insurance, internet&lt;/td&gt;
      &lt;td&gt;$550&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Fri Apr 17&lt;/td&gt;
      &lt;td&gt;Electricity, student loan, streaming, gym, May rent&lt;/td&gt;
      &lt;td&gt;$1,530&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Fri May 1&lt;/td&gt;
      &lt;td&gt;Car loan, phone, car insurance, internet&lt;/td&gt;
      &lt;td&gt;$550&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Fri May 15&lt;/td&gt;
      &lt;td&gt;Electricity, student loan, streaming, gym&lt;/td&gt;
      &lt;td&gt;$330&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Fri May 29&lt;/td&gt;
      &lt;td&gt;June rent, car loan, phone, car insurance&lt;/td&gt;
      &lt;td&gt;$1,690&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Fri Jun 12&lt;/td&gt;
      &lt;td&gt;Internet, electricity, student loan, streaming, gym&lt;/td&gt;
      &lt;td&gt;$390&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Fri Jun 26&lt;/td&gt;
      &lt;td&gt;July rent, car loan, phone, car insurance&lt;/td&gt;
      &lt;td&gt;$1,690&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Same bills, same pay, and the load on one paycheck swings from $330 to $1,690. Across 2026 on this schedule it runs from $275 (August 7) to $1,750 (August 21).&lt;/p&gt;

&lt;p&gt;Three things fall out of the table:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Rent is never paid by its own month’s paycheck.&lt;/strong&gt; Rent due on the 1st has a pay-by date in the last days of the previous month, so it always comes out of a paycheck from the month before.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The third paycheck is not spare money.&lt;/strong&gt; May 2026 has three paydays on this schedule. The third, May 29, lands just before June’s rent and ties for the heaviest load in the table.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Which months get three paydays depends on your Fridays.&lt;/strong&gt; Twenty-six biweekly paydays is 24 plus two extras. On this cadence they fall in May and October; on the alternate Fridays, starting January 2, in January and July. Weekly pay on Fridays gives 52 paydays in 2026, with five in January, May, July and October.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;two-ways-to-fix-a-lopsided-calendar&quot;&gt;Two ways to fix a lopsided calendar&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Move a due date.&lt;/strong&gt; With semimonthly pay (the 1st and 15th, say) this is the whole fix: paydays never move, so each paycheck covers the same bills every month, and if a lender agrees to move one due date, the balance holds for good. With biweekly pay it helps less, because the paycheck that is overloaded this month is a different one next month.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Smooth it with a fixed transfer.&lt;/strong&gt; Keep a separate account just for bills, and on every payday move the same amount into it: monthly bills × 12 ÷ 26. Here that is $2,080 × 12 ÷ 26 = &lt;strong&gt;$960 per paycheck&lt;/strong&gt;. Twenty-six transfers of $960 make $24,960, exactly twelve months of $2,080. Pay every bill from that account and the swing disappears from your spending money: each paycheck gives up $960, whatever the calendar does.&lt;/p&gt;

&lt;p&gt;The account needs a starting cushion, because the money arrives evenly and the bills do not. For this schedule, seeding it with one $960 transfer in January, after January’s rent, keeps it positive all year. Its lowest point is $320 on April 28, the pay-by date for May’s rent, and it ends the year back at $960.&lt;/p&gt;

&lt;h2 id=&quot;credit-cards-the-one-due-date-that-stays-put&quot;&gt;Credit cards: the one due date that stays put&lt;/h2&gt;

&lt;p&gt;Card due dates are the most predictable line on the calendar. Under Regulation Z, a card’s due date must fall on the same day of the month in every billing cycle (&lt;a href=&quot;https://www.consumerfinance.gov/rules-policy/regulations/1026/7/&quot;&gt;12 CFR 1026.7(b)(11)&lt;/a&gt;). The statement must be mailed or delivered at least 21 days before that date (&lt;a href=&quot;https://www.consumerfinance.gov/rules-policy/regulations/1026/5/&quot;&gt;§ 1026.5(b)(2)(ii)&lt;/a&gt;). And the issuer cannot set a payment cut-off earlier than 5 p.m. on the due date (&lt;a href=&quot;https://www.consumerfinance.gov/rules-policy/regulations/1026/10/&quot;&gt;§ 1026.10(b)(2)(ii)&lt;/a&gt;). Enter the card once and it will not wander.&lt;/p&gt;

&lt;h2 id=&quot;if-a-date-slips-anyway&quot;&gt;If a date slips anyway&lt;/h2&gt;

&lt;p&gt;The threshold worth knowing is 30 days. The CFPB’s guide to &lt;a href=&quot;https://files.consumerfinance.gov/f/documents/cfpb_understand_your_credit_report_handout.pdf&quot;&gt;reading your credit report&lt;/a&gt; says an account is usually still reported as current if it is paid within 30 days of the due date. A late fee can arrive much sooner, depending on your agreement. Past that point, negative payment history can generally be reported for &lt;a href=&quot;https://www.consumerfinance.gov/ask-cfpb/how-long-does-information-stay-on-my-credit-report-en-323/&quot;&gt;up to seven years&lt;/a&gt;. A payment you notice on day three is a fee problem. On day thirty-one it can become a credit-history problem.&lt;/p&gt;

&lt;h2 id=&quot;where-allpaid-fits-and-where-it-doesnt&quot;&gt;Where AllPaid fits, and where it doesn’t&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/apps/allpaid/&quot;&gt;AllPaid&lt;/a&gt; holds the bill side of this calendar. Each bill gets a name, an optional amount, a due date and a repeat, such as monthly or yearly. Type a name it recognises, such as Netflix or rent, and it offers to fill in the cycle and category, plus a typical price for common subscriptions; amounts for rent and utilities are left to you.&lt;/p&gt;

&lt;p&gt;The calendar button opens the Monthly Summary: the month as a grid with a dot on every day a bill is due, which changes colour once the bill is paid, and three totals across the top for due, paid and remaining. Reminders arrive at 9:00 local time the day before a bill is due. Pro adds earlier ones, such as three days or a week ahead, and one on the due day itself. To build in the CFPB’s margin, either enter the pay-by date as the due date or use the three-day reminder. From the notification you can mark the bill paid or snooze it for two hours or until tomorrow, and marking a repeating bill paid moves it to its next due date. Ask Siri “What bills are due in AllPaid” and it reads out the next seven days.&lt;/p&gt;

&lt;p&gt;Two decisions are deliberate. A bill whose date has gone by is labelled &lt;em&gt;Due date passed&lt;/em&gt;, not &lt;em&gt;overdue&lt;/em&gt;, because the app’s design brief asks for calm, neutral language and rules out overdue panic states. And AllPaid never asks for a bank login; the reasoning is in &lt;a href=&quot;/journal/i-will-not-ask-for-your-bank-login/&quot;&gt;I will not ask for your bank login&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That second decision is also its limit here. AllPaid does not know when you are paid and has no income field, so steps 3 to 5 (paydays, pay-period totals, the transfer amount) stay on paper or in a note. It also cannot remind you about a bill you never entered.&lt;/p&gt;

&lt;h2 id=&quot;tldr&quot;&gt;TL;DR&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;A bill calendar shows which paycheck pays which bill. A balanced month can still hide one overloaded fortnight.&lt;/li&gt;
  &lt;li&gt;Plan around pay-by dates, not due dates. The CFPB suggests 2 to 3 days early online and at least 7 days early by mail.&lt;/li&gt;
  &lt;li&gt;Biweekly pay drifts. In the example, the same $2,080 of bills puts anywhere from $330 to $1,690 on a single paycheck.&lt;/li&gt;
  &lt;li&gt;The smoothing formula is monthly bills × 12 ÷ 26. Move that much to a bills account every payday, and seed it with one transfer.&lt;/li&gt;
  &lt;li&gt;Card due dates are fixed by rule: same day every month, statement 21 days ahead, cut-off no earlier than 5 p.m.&lt;/li&gt;
  &lt;li&gt;Paid within 30 days, an account is usually still reported current. Fees can start sooner.&lt;/li&gt;
&lt;/ul&gt;
</content>
  </entry>

  <entry>
    <title>Your photos shouldn&apos;t ride the elevator to a stranger&apos;s data centre</title>
    <link href="https://lagerland-apps.github.io/journal/your-photos-shouldnt-ride-the-elevator/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/your-photos-shouldnt-ride-the-elevator/</id>
    <published>2026-03-28T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Almost every online image converter you&apos;ve used in the last decade uploaded your file to a server you don&apos;t control, processed it there, and gave you back a download. That is convenient, and it has real privacy costs. MediaKit is the studio&apos;s argument that 133 of those tools should run on your Mac instead.</summary>
    <content type="html">&lt;p&gt;Think of the last time this week you needed to convert a media file: a HEIC photo to JPG, a video compressed for Slack, two PDFs merged, a screen recording’s audio extracted to MP3.&lt;/p&gt;

&lt;p&gt;Most people use a free online converter for that. You upload the file to &lt;em&gt;cloudconverter.com&lt;/em&gt; or &lt;em&gt;ilovepdf.com&lt;/em&gt; or &lt;em&gt;tinypng.com&lt;/em&gt; or one of a hundred near-identical sites, wait, download the result, and move on. The same reflex reaches documents with your home address printed on them, &lt;a href=&quot;/journal/vet-paperwork-stays-on-your-phone/&quot;&gt;vet paperwork, for one&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Almost none of those tools needed your file to leave your device. Uploading is convenient, but it sends private files somewhere they never needed to go, and &lt;a href=&quot;/apps/mediakit/&quot;&gt;MediaKit&lt;/a&gt; is the studio’s argument that the whole category of conversion tools belongs on your Mac.&lt;/p&gt;

&lt;h2 id=&quot;what-does-convert-online-actually-do-to-your-file&quot;&gt;What does “convert online” actually do to your file?&lt;/h2&gt;

&lt;p&gt;When you use a free online converter, the file goes through these steps:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;It leaves your machine, encrypted in transit.&lt;/li&gt;
  &lt;li&gt;It lands on the operator’s storage, sometimes encrypted at rest, sometimes not.&lt;/li&gt;
  &lt;li&gt;Their conversion pipeline processes it, which typically takes seconds.&lt;/li&gt;
  &lt;li&gt;It is held in storage, often for hours, sometimes for days, depending on the operator’s retention policy.&lt;/li&gt;
  &lt;li&gt;You download it.&lt;/li&gt;
  &lt;li&gt;It &lt;em&gt;may or may not&lt;/em&gt; be deleted from the operator’s storage according to their stated policy, which you have no way to verify.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You notice the first and last steps. The privacy questions sit in the middle ones. The file you converted contained whatever it contained (a photograph of your kitchen, a screenshot of an email, a PDF of your medical records, a video of your child), and it now lives, briefly or not so briefly, on infrastructure you do not control.&lt;/p&gt;

&lt;p&gt;Most online converters are run by small teams, and most try to delete files promptly. The problem is the design: files leave your machine for processing that doesn’t require it, and you have to trust the operator to be careful in the right way.&lt;/p&gt;

&lt;h2 id=&quot;apple-silicon-changed-the-math&quot;&gt;Apple Silicon changed the math&lt;/h2&gt;

&lt;p&gt;Cloud converters dominated because local conversion used to be slow. In 2015, compressing a 4K video on a laptop took twenty minutes. Uploading it to a cloud service that compressed it in thirty seconds was simply faster, even counting the upload.&lt;/p&gt;

&lt;p&gt;Apple Silicon closed that gap. Modern Macs have hardware video encoders that compress at multiples of real-time speed, with ProRes acceleration, HEIC encoding, and AV1 decoding all on the chip. Local performance is now competitive with the cloud round trip, and sometimes faster.&lt;/p&gt;

&lt;p&gt;For images and PDFs, local processing was always faster. Those moved to the cloud because web tools are easier to ship: one runs in any browser, while a desktop tool has to be installed. That is real friction, and we think the privacy you keep is worth it.&lt;/p&gt;

&lt;h2 id=&quot;what-mediakit-specifically-does&quot;&gt;What MediaKit specifically does&lt;/h2&gt;

&lt;p&gt;MediaKit is a Mac app with 133 local conversion tools, organised by media type:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Video&lt;/strong&gt;: compression for YouTube/Instagram/Slack, format conversion (MP4, HEVC, AV1, ProRes), resolution and bitrate adjustment, frame extraction, audio extraction.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Image&lt;/strong&gt;: HEIC↔JPG↔PNG↔WebP, bulk operations across folders, resize/crop/rotate, EXIF stripping, format-specific optimisation.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Audio&lt;/strong&gt;: format conversion, bitrate adjustment, channel mixing, silence trimming.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;PDF&lt;/strong&gt;: merge, split, redact, sign, OCR, page reorder, compress.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Archive&lt;/strong&gt;: ZIP, TAR, GZIP, and &lt;strong&gt;RAR v5 extraction natively on Apple Silicon&lt;/strong&gt;. That has long been a pain point for people who still get RAR archives in 2026, which happens more often than you’d think, since academic and design workflows use the format heavily.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every tool runs entirely on the Mac, so nothing is uploaded and there is no operator retention policy to read. For the most common video job, getting a clip under an email attachment limit, the limits and the bitrate arithmetic are in &lt;a href=&quot;/journal/compress-a-video-for-email/&quot;&gt;a separate guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;All the tools support &lt;strong&gt;Shortcuts integration&lt;/strong&gt;, so you can chain them into automated workflows. &lt;em&gt;“Compress all videos in this Downloads folder, output to ~/Compressed, delete originals over 100MB”&lt;/em&gt; is one Shortcut; it runs on a schedule and never touches the internet.&lt;/p&gt;

&lt;h2 id=&quot;the-freemium-decision&quot;&gt;The freemium decision&lt;/h2&gt;

&lt;p&gt;Pricing was the decision we argued about most before launch.&lt;/p&gt;

&lt;p&gt;MediaKit shipped with &lt;strong&gt;five permanently free tools&lt;/strong&gt; (Video Compress, Image Compress, Image Resize, Audio Convert, PDF Compress), which between them probably cover 70% of casual use cases, and a single Pro tier that unlocks the remaining 128 tools and batch processing across all of them. There is also a free 3-day trial of &lt;em&gt;all&lt;/em&gt; tools, so you can try everything before deciding.&lt;/p&gt;

&lt;p&gt;We wanted a free path that people would actually use. Five tools is enough that a casual user could go years without paying, and that’s fine; the app should be useful first.&lt;/p&gt;

&lt;p&gt;The long tail of tools is what makes MediaKit worth paying for to a &lt;em&gt;power user&lt;/em&gt;, and power users are the ones who fund building it. So power users pay because they get a lot out of the app, and casual users pay nothing for the basics.&lt;/p&gt;

&lt;h2 id=&quot;in-short&quot;&gt;In short&lt;/h2&gt;

&lt;p&gt;If you habitually use online converters, &lt;a href=&quot;/apps/mediakit/&quot;&gt;MediaKit&lt;/a&gt; is our case that you don’t need to. The Mac in front of you can do the same processing locally, faster than you’d expect, and your files stay on it.&lt;/p&gt;

&lt;p&gt;The free tier covers the common cases. The Pro unlock covers everything else, including the obscure jobs (RAR v5 on Apple Silicon, batch HEIC stripping, PDF redaction with verifiable removal) that most online services either don’t support or charge a subscription for.&lt;/p&gt;

&lt;p&gt;It’s the last weekend of March. If you have a stack of media files you’ve been meaning to process, this is a way to do it without uploading any of them.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>How to sleep after a night shift: the drive home, the dark room, the nap and the days off</title>
    <link href="https://lagerland-apps.github.io/journal/how-to-sleep-after-a-night-shift/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/how-to-sleep-after-a-night-shift/</id>
    <published>2026-03-21T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Sleeping in daylight after a night shift is hard for reasons that have little to do with discipline. Your body clock says it is morning, the street is awake and the sun is up. Some of the most specific public advice on what to do about it sits in a free NIOSH training course written for nurses. Below it is in the order you will need it: the end of the shift, the drive home, the bedroom, the nap and the days off.</summary>
    <content type="html">&lt;p&gt;Night workers usually get less sleep, and lower-quality sleep, than people who sleep at night. That is the starting point of the &lt;a href=&quot;https://www.cdc.gov/niosh/work-hour-training-for-nurses/&quot;&gt;NIOSH Training for Nurses on Shift Work and Long Work Hours&lt;/a&gt;, a free course from the U.S. National Institute for Occupational Safety and Health. It was written for nurses, but its sleep advice does not depend on the job. Unless another source is named, everything below comes from it.&lt;/p&gt;

&lt;h2 id=&quot;the-day-after-a-night-shift-in-order&quot;&gt;The day after a night shift, in order&lt;/h2&gt;

&lt;p&gt;NIOSH’s example has the worker home at 8 a.m. Move the times to fit your own shift.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;When&lt;/th&gt;
      &lt;th&gt;What to do&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;First half of the shift&lt;/td&gt;
      &lt;td&gt;Spend as much time as you can in bright light. If you use caffeine, have it now.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Second half of the shift&lt;/td&gt;
      &lt;td&gt;Cut back on bright light unless you are very sleepy. Stop caffeine several hours before the end.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;The drive home&lt;/td&gt;
      &lt;td&gt;Dark sunglasses only if someone else is driving.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Home, around 8 a.m.&lt;/td&gt;
      &lt;td&gt;Go straight to bed. If you haven’t eaten for hours, have a small meal with protein and carbohydrate first.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Morning to early afternoon&lt;/td&gt;
      &lt;td&gt;Sleep as long as you can. The more sleep you get before 2 p.m., the better rested you will be.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Afternoon or evening&lt;/td&gt;
      &lt;td&gt;Nap before the next night shift if you can.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Days off&lt;/td&gt;
      &lt;td&gt;Stay up until 3 or 4 a.m. and sleep until noon or 1 p.m.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Each row is explained below with its source. The light rows come from the course’s &lt;a href=&quot;https://www.cdc.gov/niosh/work-hour-training-for-nurses/longhours/mod9/03.html&quot;&gt;night-shift light page&lt;/a&gt;, which calls the body-clock benefit for permanent night workers theoretical; bright light early in the shift is mainly about staying alert.&lt;/p&gt;

&lt;h2 id=&quot;make-the-bedroom-dark-enough-that-you-cant-see-your-hand&quot;&gt;Make the bedroom dark enough that you can’t see your hand&lt;/h2&gt;

&lt;p&gt;NIOSH sets the bar for a daytime bedroom at a room “so dark you cannot see your hand in front of your eyes” (&lt;a href=&quot;https://www.cdc.gov/niosh/work-hour-training-for-nurses/longhours/mod9/05.html&quot;&gt;sleep after a night shift&lt;/a&gt;). Closing the curtains rarely gets there. The &lt;a href=&quot;https://www.cdc.gov/niosh/work-hour-training-for-nurses/longhours/mod6/02.html&quot;&gt;bedroom light checklist&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Windows:&lt;/strong&gt; room-darkening shades or heavy, lined drapes, adjusted so no light leaks around the edges. Blinds let too much through.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Doors and hallways:&lt;/strong&gt; turn off hall lights or put a draft stopper under the door. If light still gets in, wear an eye mask for the whole sleep.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Inside the room:&lt;/strong&gt; remove or cover anything that glows, such as a lit clock, a phone or a TV.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The bathroom trip:&lt;/strong&gt; keep the path dark and clear, with a dim red nightlight if you need one.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Noise is the other half. NIOSH suggests &lt;a href=&quot;https://www.cdc.gov/niosh/work-hour-training-for-nurses/longhours/mod6/03.html&quot;&gt;earplugs, a fan or a white-noise machine&lt;/a&gt;, asking the household to keep out of the bedroom and keep the noise down, and setting the phone to Do Not Disturb with chosen contacts allowed through for emergencies. Keep the room cool, and turn the clock face away so you are not checking the time.&lt;/p&gt;

&lt;h2 id=&quot;caffeine-belongs-at-the-start-of-the-shift&quot;&gt;Caffeine belongs at the start of the shift&lt;/h2&gt;

&lt;p&gt;NIOSH gives caffeine’s half-life as &lt;a href=&quot;https://www.cdc.gov/niosh/work-hour-training-for-nurses/longhours/mod6/04.html&quot;&gt;5 to 6 hours&lt;/a&gt;, longer in some people, and suggests that night workers who use it have it at the start of the shift and stop several hours before the end. The arithmetic explains why: a coffee at 3 a.m. still leaves about half its caffeine in your system when you lie down at 8 or 9.&lt;/p&gt;

&lt;p&gt;The same page covers the rest of the run-up to sleep: dim lights for an hour or two before bed, no heavy or spicy meals in the 2 to 3 hours before, not too much to drink, and any alcohol several hours ahead, because it can wake you early.&lt;/p&gt;

&lt;h2 id=&quot;the-drive-home-is-the-riskiest-part-of-the-morning&quot;&gt;The drive home is the riskiest part of the morning&lt;/h2&gt;

&lt;p&gt;NIOSH notes that many nurses feel &lt;a href=&quot;https://www.cdc.gov/niosh/work-hour-training-for-nurses/longhours/mod7/08.html&quot;&gt;excessively sleepy after night shifts&lt;/a&gt; and have a higher risk of crashing on the way home. It mentions a brief nap at work before driving as something that might help, and says plainly that this has not been tested.&lt;/p&gt;

&lt;p&gt;Sunglasses are a trade-off. Blocking bright morning light on the way home may help you sleep longer afterwards, but researchers worry that it also takes away light’s alerting effect from a driver who is already very sleepy. NIOSH’s &lt;a href=&quot;https://www.cdc.gov/niosh/work-hour-training-for-nurses/longhours/mod6/07.html&quot;&gt;safest approach&lt;/a&gt; is to wear dark sunglasses after a night shift only if someone else is driving, put them on before you step outside, and keep them on until you are back in a dark room.&lt;/p&gt;

&lt;h2 id=&quot;the-nap-before-the-next-night&quot;&gt;The nap before the next night&lt;/h2&gt;

&lt;p&gt;NIOSH recommends napping before you go back to work if you can: it adds to your total sleep and helps you stay alert through the night. This &lt;a href=&quot;https://www.cdc.gov/niosh/work-hour-training-for-nurses/longhours/mod7/06.html&quot;&gt;prophylactic nap&lt;/a&gt; is usually long, a few hours, enough to reach deeper sleep and ease the sleep pressure of the night ahead. The studies NIOSH cites:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Nap before the night shift&lt;/th&gt;
      &lt;th&gt;Result&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;1.5 hours, 3:30 to 5 p.m.&lt;/td&gt;
      &lt;td&gt;Nurses and nursing aides were more alert in the second half of their first night shift than those who didn’t nap&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2.5 hours, 7:30 to 10 p.m.&lt;/td&gt;
      &lt;td&gt;Better alertness during a simulated night shift than with no nap&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;3 hours, 2 to 5 p.m.&lt;/td&gt;
      &lt;td&gt;Higher alertness during the following night shift than with no nap&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2.5 hours, plus caffeine at the start of the shift&lt;/td&gt;
      &lt;td&gt;The combination improved alertness&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;In 2007, the American Academy of Sleep Medicine’s practice parameters rated &lt;a href=&quot;https://aasm.org/practice-parameters-published-in-the-journal-sleep-highlight-recommendations-for-the-evaluation-and-treatment-of-circadian-rhythm-sleep-disorders/&quot;&gt;planned napping before or during the night shift&lt;/a&gt; a “standard”, its highest-certainty category, for improving night workers’ alertness and performance.&lt;/p&gt;

&lt;p&gt;Long naps have a cost: grogginess on waking, called sleep inertia. Waking after about &lt;a href=&quot;https://www.cdc.gov/niosh/work-hour-training-for-nurses/longhours/mod7/05.html&quot;&gt;20 or about 90 minutes&lt;/a&gt; tends to leave you less groggy than waking after about an hour, in deep sleep, and that grogginess may clear within 15 to 30 minutes. It &lt;a href=&quot;https://www.cdc.gov/niosh/work-hour-training-for-nurses/longhours/mod7/03.html&quot;&gt;lasts longer&lt;/a&gt; when you are short of sleep, so leave time before you drive or do anything where a mistake matters. If you work on call, where a phone can wake you at any hour, &lt;a href=&quot;/journal/how-to-sleep-on-call/&quot;&gt;how to sleep on call&lt;/a&gt; covers that kind of grogginess in more detail.&lt;/p&gt;

&lt;h2 id=&quot;days-off-keep-part-of-the-window&quot;&gt;Days off: keep part of the window&lt;/h2&gt;

&lt;p&gt;Switching all the way back to night sleep on every day off keeps your body clock in something close to permanent jet lag. The &lt;a href=&quot;https://www.cdc.gov/niosh/work-hour-training-for-nurses/longhours/mod9/06.html&quot;&gt;compromise NIOSH describes&lt;/a&gt;: on days off, stay up until 3 or 4 a.m. and sleep until noon or 1 p.m. That way a block such as 8 a.m. to noon is sleep time on work days and days off alike.&lt;/p&gt;

&lt;p&gt;The same page warns against the opposite shortcut: staying awake all day before the first night of a run, or after the last one. You end up awake for too many hours, which raises the risk of accidents and, over time, of chronic sleep loss. The course does not cover rotating schedules in detail; rotating workers who struggle to adjust are pointed to a sleep specialist.&lt;/p&gt;

&lt;h2 id=&quot;when-its-more-than-a-bad-week&quot;&gt;When it’s more than a bad week&lt;/h2&gt;

&lt;p&gt;Persistent sleep problems should not be ignored, NIOSH says, and a &lt;a href=&quot;https://www.cdc.gov/niosh/work-hour-training-for-nurses/longhours/mod6/15.html&quot;&gt;sleep disorder&lt;/a&gt; such as sleep apnea or insomnia can make enough sleep impossible until it is treated. The American Academy of Sleep Medicine’s page on &lt;a href=&quot;https://sleepeducation.org/sleep-disorders/shift-work/&quot;&gt;shift work disorder&lt;/a&gt; draws a similar line: a new shift is hard for many people at first, but if after several weeks you still have trouble falling or staying asleep, or feel tired even after 7 to 8 hours, you may have shift work disorder. That is a conversation for your doctor or a sleep specialist, and so is any sleep aid or supplement.&lt;/p&gt;

&lt;h2 id=&quot;where-aftershift-fits&quot;&gt;Where AfterShift fits&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/apps/aftershift/&quot;&gt;AfterShift&lt;/a&gt; is an iPhone app for people on night, rotating and on-call schedules. It is an informational tracker: it shows what your sleep is doing around your shifts, but it does not diagnose or treat anything, and none of the advice above depends on it. Where it meets that advice:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;It reads your sleep and labels it.&lt;/strong&gt; AfterShift reads sleep from Apple Health (it never writes or shares that data) and tells you where each sleep fell: after a night shift, before one, between shifts or on a recovery day.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;It shows whether bedroom changes worked.&lt;/strong&gt; For each sleep you see time asleep against time in bed, sleep efficiency, the sleep midpoint and whether you slept inside the planned window. If new blackout shades help, that is where it shows.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;It plans the next window.&lt;/strong&gt; Add your next shift and the Today tab shows a planned sleep window, flags one shorter than six hours, and suggests a short 20 to 30 minute nap when recovery time is tight. If you tell it you can’t nap, it stops suggesting nap windows. The long pre-shift naps in the NIOSH table are yours to plan; Log Nap records them and asks how the nap went, including whether you woke up groggy.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;It times caffeine against your sleep, not the clock.&lt;/strong&gt; Setup asks for your one-way commute and your caffeine sensitivity, which sets a cutoff of 4, 6 or 8 hours before sleep. Caffeine you log from the Today tab is marked good, borderline or late over the last 14 days.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The Coach tab&lt;/strong&gt; has short explainers on light, naps, caffeine timing and the daytime sleep environment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Shift Recovery Score is built from sleep length, continuity and the timing of your next shift, and like everything else on the screen it is there to inform you; it doesn’t judge your sleep. There is no account, and your data stays on your device; the &lt;a href=&quot;/apps/aftershift/privacy/&quot;&gt;privacy page&lt;/a&gt; has the details, and &lt;a href=&quot;/journal/building-a-sleep-app-for-night-shifts/&quot;&gt;the design post&lt;/a&gt; explains why the app treats daytime sleep as normal.&lt;/p&gt;

&lt;p&gt;The advice itself is free and older than any app: a dark room, early caffeine, a nap before the next night, and a doctor if the sleep still won’t come.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>The case for a native App Store screenshot tool</title>
    <link href="https://lagerland-apps.github.io/journal/the-case-for-native-screenshot-tooling/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/the-case-for-native-screenshot-tooling/</id>
    <published>2026-03-14T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">App Store screenshots do more marketing work for an indie app than anything else, and most indie developers, past versions of me included, treat them as the worst chore of every release. Mockly is the studio&apos;s case that this workflow belongs in a native Mac app, and that a YAML-driven CI script is the wrong home for it.</summary>
    <content type="html">&lt;p&gt;App Store screenshots are the most underrated assets in indie iOS marketing. They are the first thing a prospective user sees in a search result, and they convert better than any description, keyword, or rating. Yet most indie developers I know treat them as the worst chore of every release (that’s anecdote, not a survey).&lt;/p&gt;

&lt;p&gt;I treated them that way for five years. &lt;a href=&quot;/apps/mockly/&quot;&gt;Mockly&lt;/a&gt; is the studio’s attempt at something better, and the rest of this post is what I learned shipping it.&lt;/p&gt;

&lt;h2 id=&quot;what-is-the-fastlane-status-quo-for-app-store-screenshots&quot;&gt;What is the fastlane status quo for App Store screenshots?&lt;/h2&gt;

&lt;p&gt;In the iOS indie world, most people generate screenshots with &lt;strong&gt;fastlane snapshot&lt;/strong&gt;, a Ruby tool that drives the iOS simulator, takes screenshots in every required device size, and writes them to disk. Add &lt;strong&gt;fastlane frameit&lt;/strong&gt; (device frames) and &lt;strong&gt;fastlane deliver&lt;/strong&gt; (upload to App Store Connect) and you have a complete pipeline.&lt;/p&gt;

&lt;p&gt;Fastlane deserves credit. It is genuinely useful, its team has done indie developers a public service for nearly a decade, and the tool is open source. If you already have a heavily customised CI pipeline and your screenshots fit fastlane’s templates, it is a reasonable choice.&lt;/p&gt;

&lt;p&gt;It is not comfortable to use, though. The workflow is:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Write Swift UI tests that drive your app to specific screens.&lt;/li&gt;
  &lt;li&gt;Maintain a YAML config of devices, locales, and target screens.&lt;/li&gt;
  &lt;li&gt;Run a Ruby command-line tool that takes 30-90 minutes for a multi-locale ship.&lt;/li&gt;
  &lt;li&gt;Hope that nothing in iOS or Xcode broke the simulator automation since last release.&lt;/li&gt;
  &lt;li&gt;Manually swap or recompose any screenshot that needs editorial work: text overlays, multiple devices in one image, before/after pairs.&lt;/li&gt;
  &lt;li&gt;Ship.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Every step adds friction, and it compounds. The Swift UI tests rot. The YAML grows. The simulator changes its rendering between Xcode versions without telling you. The editorial work happens in a separate tool (Pixelmator, Photoshop, or hand-coded SwiftUI), so the editorial assets and the automated assets drift apart. By the third release, half the studios I know have given up on the automated path and are screenshotting the simulator by hand.&lt;/p&gt;

&lt;h2 id=&quot;the-native-app-argument&quot;&gt;The native-app argument&lt;/h2&gt;

&lt;p&gt;Mockly is built on the bet that &lt;strong&gt;most indie screenshot work is a GUI problem&lt;/strong&gt;, and automation solves the smaller part of it.&lt;/p&gt;

&lt;p&gt;A GUI tool lets you manipulate the asset directly. You drag the screenshot from the simulator into the app, pick a device frame from a library, add a text overlay, compose multi-device layouts, and see the final result immediately. The locale switcher swaps the underlying screenshot and keeps the layout. The 3D frames are rendered live instead of laid on as PNG overlays, so a four-degree rotation gets proper perspective and lighting, which a flat composite cannot match.&lt;/p&gt;

&lt;p&gt;The output is the same PNG files at the App Store’s required dimensions. The &lt;em&gt;workflow&lt;/em&gt; is what changes. Each screenshot becomes a small asset you own, edit and re-export when needed, where a pipeline would regenerate it slightly differently every time the simulator runs.&lt;/p&gt;

&lt;p&gt;That workflow fits studios that ship a polished, carefully edited set of screenshots: several devices in one image, overlay copy, motion blur on transition shots.&lt;/p&gt;

&lt;h2 id=&quot;what-mockly-specifically-does&quot;&gt;What Mockly specifically does&lt;/h2&gt;

&lt;p&gt;The feature set, briefly:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;3D Metal-rendered device frames.&lt;/strong&gt; Every iPhone and iPad model from the last six years, rendered when you compose the screenshot. Rotation, perspective, lighting, and reflections are physically rendered.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Localised composition.&lt;/strong&gt; A single layout, with text, multiple devices, and overlays, exports across 20+ App Store regions in one click. The locale switcher swaps screenshots and translates copy.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Direct upload to App Store Connect.&lt;/strong&gt; You skip the fastlane deliver step. The app talks to the ASC API and pushes to the right per-locale slot.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Templates.&lt;/strong&gt; A library of professionally designed templates for common patterns: the four-screenshot hook, the before-and-after, the device-and-watch pairing.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Editorial workflow.&lt;/strong&gt; Custom layouts, free positioning, drag-and-drop: the full composition tool that fastlane doesn’t try to be.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mockly deliberately leaves the automation pipeline alone. If your studio has a deep CI/CD investment and screenshots that regenerate from running tests on every release, keep fastlane in your stack. Mockly covers the editorial step upstream of the pipeline, &lt;em&gt;deciding what the screenshot says&lt;/em&gt;, for the studios where that is most of the work.&lt;/p&gt;

&lt;h2 id=&quot;why-1299-lifetime-with-family-sharing&quot;&gt;Why $12.99 lifetime, with Family Sharing&lt;/h2&gt;

&lt;p&gt;The pricing follows the &lt;a href=&quot;/journal/native-mac-client-for-app-store-connect/&quot;&gt;AppMeta pricing decision&lt;/a&gt; from a few weeks back: a one-time purchase with lifetime access. AppMeta later added a yearly option; Mockly has no subscription at all.&lt;/p&gt;

&lt;p&gt;Mockly adds &lt;strong&gt;Family Sharing support&lt;/strong&gt;. A two-developer studio (me and a co-founder, two indie partners, a couple-run studio) can share a single $12.99 license. I chose this on purpose. The alternative was per-seat pricing, which suits SaaS and doesn’t suit a tool that small studios use now and then.&lt;/p&gt;

&lt;p&gt;The studio loses some revenue to Family Sharing. In exchange, I think, it gets the right relationship with the user: a small indie tool should treat its small indie users like a household, and not like a contract.&lt;/p&gt;

&lt;h2 id=&quot;who-should-stay-with-fastlane&quot;&gt;Who should stay with fastlane&lt;/h2&gt;

&lt;p&gt;Not every iOS developer should switch to Mockly. Fastlane serves the largest, most automated indie pipelines well, and many of them have years of customisation that would be expensive to abandon.&lt;/p&gt;

&lt;p&gt;My claim is narrower. A sizeable share of indie developers, the studios where screenshot work is editorial first and pipelined second, would be better served by a GUI tool than a CI script. Almost nobody builds GUI tools for indie iOS workflows, because the audience is “just” tens of thousands of developers worldwide.&lt;/p&gt;

&lt;p&gt;This studio happens to be part of that audience, and &lt;a href=&quot;/apps/mockly/&quot;&gt;Mockly&lt;/a&gt; is for it: $12.99, lifetime, with Family Sharing. If it doesn’t fit your workflow, fastlane will still be there next release.&lt;/p&gt;

&lt;p&gt;If you’ve ever sworn at a Ruby script in the middle of a Friday ship, this might be the weekend to reconsider which parts of the chore you actually need.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>Why I shipped a Strong-style logger that nobody asked for</title>
    <link href="https://lagerland-apps.github.io/journal/the-strength-logger-no-one-asked-for/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/the-strength-logger-no-one-asked-for/</id>
    <published>2026-03-07T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Strong, Hevy and Fitbod already exist, and the market for strength-training loggers is well served. I shipped GymLogger X anyway, because I wanted workouts to be logged on the wrist instead of on the phone screen.</summary>
    <content type="html">&lt;p&gt;It’s the first weekend of March. The clocks shift forward in the US tomorrow night, which, through a quirk of biology, makes this the worst week of the year to &lt;a href=&quot;/journal/choosing-a-strength-program-you-will-finish/&quot;&gt;start a new training program&lt;/a&gt;. More on that later.&lt;/p&gt;

&lt;p&gt;This weekend’s post is about why this studio shipped a strength-training logger at all, when the category is one of the best served on the App Store.&lt;/p&gt;

&lt;h2 id=&quot;why-ship-another-strength-logger-into-a-crowded-category&quot;&gt;Why ship another strength logger into a crowded category?&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/apps/gymlogger-x/&quot;&gt;GymLogger X&lt;/a&gt; competes with Strong (the long-running incumbent), Hevy (the design-led upstart), Fitbod (the AI-program one), Caliber (the coach-network one) and a long tail of niche loggers. They are all good apps, and the category is not under-served in any obvious way.&lt;/p&gt;

&lt;p&gt;When I started building GymLogger X in late 2025, friends in the indie community asked me, gently, why. Features weren’t the reason. The incumbents had one specific thing structurally wrong.&lt;/p&gt;

&lt;h2 id=&quot;logging-on-the-wrist&quot;&gt;Logging on the wrist&lt;/h2&gt;

&lt;p&gt;Most strength loggers on the App Store are designed around the phone. The session is laid out for the phone screen, and the watch app, where there is one, is a smaller version of it that lets you peek at the next set, maybe start a rest timer, and sometimes log a set if you tap through three menus.&lt;/p&gt;

&lt;p&gt;That is backwards for how a gym session goes. Your phone sits in a bag or on a bench, while your watch is on your wrist, with you between sets. So the watch is where logging should happen.&lt;/p&gt;

&lt;p&gt;Building a logger around the wrist is harder than building a phone-first one. The screen is small, the input options are limited (Digital Crown, taps, voice), the latency budget for syncing back to the phone is tight, and Apple’s WatchKit constraints are real. Most apps skip it because the engineering cost is significant and fewer people will &lt;em&gt;use&lt;/em&gt; it than the iPhone audience.&lt;/p&gt;

&lt;p&gt;I shipped GymLogger X anyway, with the watch as the interface you log on and the phone as the engine in your bag. You start the session on the iPhone, which keeps the record. After that, set entry and rest timers happen on the wrist, and live heart rate is there at a glance. The phone handles analytics, program editing and history review, which benefit from a bigger screen.&lt;/p&gt;

&lt;p&gt;The feedback so far: the people who want this &lt;em&gt;really&lt;/em&gt; want it, and the people who don’t want it don’t notice it’s there. I’m fine with both.&lt;/p&gt;

&lt;h2 id=&quot;plateau-detection-that-doesnt-lecture&quot;&gt;Plateau detection that doesn’t lecture&lt;/h2&gt;

&lt;p&gt;The other half of the bet is the analytics.&lt;/p&gt;

&lt;p&gt;Most strength loggers track sets and reps and stop there, and their Pro tiers add some trend lines. In my experience none of them will tell you: &lt;em&gt;your bench press has been stalled at 100kg×5 for nine weeks across three different programs, and the most likely cause is your recovery, not your programming.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;GymLogger X Pro tries to make that observation, gently. The &lt;em&gt;plateau detection&lt;/em&gt; feature compares the estimated one-rep max across your four most recent sessions of each exercise and flags the exercise when that number has stopped climbing while your training volume holds steady, which means it has stalled despite consistent effort. The output is a flag on the exercise, not a notification. It names the likely cause (too much volume, intensity held too high, too little variation, or too little recovery) and suggests two things to try, such as a deload week or a change of rep range. The progress it measures is each lift’s estimated one-rep max, and &lt;a href=&quot;/journal/how-to-estimate-your-one-rep-max/&quot;&gt;how that estimate is calculated, and where the formulas stop being trustworthy&lt;/a&gt;, has its own post.&lt;/p&gt;

&lt;p&gt;It does &lt;em&gt;not&lt;/em&gt; restructure your program for you, change your weights, or send you a coach’s nag. Other apps have those features. I think they are things the user should choose to do, and not the app’s place to impose. Plateau detection in GymLogger X is information, and the next move is yours. If it points toward a lighter week, &lt;a href=&quot;/journal/when-to-deload/&quot;&gt;when to deload&lt;/a&gt; covers the signs and what the evidence says.&lt;/p&gt;

&lt;h2 id=&quot;the-lifetime-price&quot;&gt;The lifetime price&lt;/h2&gt;

&lt;p&gt;GymLogger X ships with the freemium model the studio has stuck to: core logging is free for good, Pro is $17.99/year, and there is a one-time $39.99 lifetime option for users who don’t want a subscription on a tool they intend to use for a decade.&lt;/p&gt;

&lt;p&gt;The lifetime tier is the one I get asked about most. For a studio chasing recurring revenue, the math on it is poor. A user who buys lifetime in year one and uses the app for seven years has paid the studio a fraction of what an annual subscriber would have. The tier exists anyway because strength training is a long-term practice, and a user’s training history shouldn’t depend on keeping a subscription going.&lt;/p&gt;

&lt;p&gt;About 30% of GymLogger X paid users choose the lifetime tier. They are vocal and loyal, and they are the users I’m proudest to serve.&lt;/p&gt;

&lt;h2 id=&quot;the-daylight-saving-note&quot;&gt;The daylight-saving note&lt;/h2&gt;

&lt;p&gt;Back to the calendar. This weekend the US shifts to daylight-saving time. Most US adults will lose an hour of sleep on Sunday night, and most of them won’t realise the loss has measurable consequences for the following week’s training.&lt;/p&gt;

&lt;p&gt;The research on this is unambiguous. Acute sleep restriction reduces strength performance by 5-10% the next day, noticeably raises perceived exertion, and depresses recovery markers (HRV, resting heart rate) for several days. In the gym it shows up as a lift that felt easy last Tuesday feeling heavy this Tuesday, with the lifter blaming their effort instead of their sleep. If you rate your sets, &lt;a href=&quot;/journal/rpe-and-rir-explained/&quot;&gt;how RPE and reps in reserve work&lt;/a&gt; explains why the same load can rate harder after a short night.&lt;/p&gt;

&lt;p&gt;If you started a new strength program on January 1 and have been progressing well, this is the week the curve will flatten, and the time change is the cause. Take Tuesday’s session at last week’s weights instead of pushing for new ones, and resume normal progression next week. GymLogger X won’t lecture you about it, but I will.&lt;/p&gt;

&lt;h2 id=&quot;the-short-version&quot;&gt;The short version&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/apps/gymlogger-x/&quot;&gt;GymLogger X&lt;/a&gt; exists because the category had a structural gap, logging designed for the wrist, and nobody seemed to be filling it. It has a lifetime price because strength training is a long game, and plateau detection because the data needs someone to interpret it.&lt;/p&gt;

&lt;p&gt;For the polished iPhone-first side of strength training, the studio also ships &lt;a href=&quot;/apps/liftlog/&quot;&gt;LiftLog&lt;/a&gt;, a sister app with a completely different pricing experiment. The two serve different lifters.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>Forty chess opponents, and none of them are me</title>
    <link href="https://lagerland-apps.github.io/journal/forty-chess-opponents/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/forty-chess-opponents/</id>
    <published>2026-02-28T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Of all the decisions in Chessful&apos;s design, including the engine, the analysis, and the spaced-repetition trainer, the hardest was making the app feel like forty different people. The usual approach is one engine wearing forty hats.</summary>
    <content type="html">&lt;p&gt;I learned chess from my grandfather and never got past competent. The reason I built &lt;a href=&quot;/apps/chessful/&quot;&gt;Chessful&lt;/a&gt; is precisely that gap: I wanted an app that explained what I’d done wrong in a way my grandfather would have, in plain language, instead of pointing at a centipawn evaluation graph and expecting me to read it.&lt;/p&gt;

&lt;p&gt;The app shipped with two features that took disproportionate engineering effort. One was the post-game analysis, which is the feature users actually mention. The other was forty distinct AI opponents, which carry everything else without anyone noticing. This post covers both.&lt;/p&gt;

&lt;h2 id=&quot;whats-wrong-with-the-slider-based-chess-opponent&quot;&gt;What’s wrong with the slider-based chess opponent?&lt;/h2&gt;

&lt;p&gt;Most chess apps offer a slider from Level 1 (weak) to Level 20 (engine-strong). The slider feels reasonable until you play it for a week and realise something specific:&lt;/p&gt;

&lt;p&gt;The engine plays the same way at every level. It just plays &lt;em&gt;worse on purpose&lt;/em&gt; at lower levels, by adding noise to its evaluation function. Level 5 is the same opponent as Level 15, making mathematically random mistakes. After a dozen games you can feel the noise. The mistakes have nothing to do with any style, and no real opponent plays that way.&lt;/p&gt;

&lt;p&gt;The result is that improvement against the engine slider doesn’t transfer well to playing humans, because humans have &lt;em&gt;characters&lt;/em&gt;. They favour certain openings. They get into trouble in specific structural positions. They have blind spots: the bishop on the long diagonal they always miss, the rook on the seventh rank they always overestimate.&lt;/p&gt;

&lt;p&gt;If you’re trying to build a chess app for improvement, the slider isn’t enough. You need opponents that feel like &lt;em&gt;people&lt;/em&gt;.&lt;/p&gt;

&lt;h2 id=&quot;the-forty-opponents&quot;&gt;The forty opponents&lt;/h2&gt;

&lt;p&gt;Chessful ships with forty AI opponents, each with a distinct rating, opening repertoire, structural preferences, and a small set of characteristic blind spots. Every opponent has a name, a portrait, and a one-paragraph backstory. They are explicitly fictional. None of them imitates a specific real grandmaster, which is a line I won’t cross, but each one is recognisable as a &lt;em&gt;type&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;There’s the aggressive Sicilian player who attacks the kingside relentlessly and sometimes overcommits. The positional grinder who exchanges pieces to reach better endgames. The fianchetto specialist who handles the long diagonals beautifully but flails in tactics. The student who plays well in opening theory but forgets it after move twelve. The 1700-rated club player who is slightly drunk on a Tuesday night and slightly sober on a Thursday morning.&lt;/p&gt;

&lt;p&gt;Each opponent is built from a base engine with a &lt;em&gt;style overlay&lt;/em&gt;: modifiers to the evaluation function that nudge it toward characteristic moves, openings, and structural decisions. The implementation is unglamorous, mostly piecewise weighting of evaluation features (mobility vs. king safety vs. pawn structure vs. material) tuned by playing thousands of games against a fixed test set and watching for behavioural drift.&lt;/p&gt;

&lt;p&gt;The result is &lt;em&gt;recognisability&lt;/em&gt;. After ten games against the aggressive Sicilian player, you start to anticipate her openings and learn where her blind spots are, and you are playing against her instead of an abstract evaluation function. That is what makes the games feel like games, and it is why improvement against Chessful’s opponents transfers to playing humans.&lt;/p&gt;

&lt;h2 id=&quot;the-post-game-analysis&quot;&gt;The post-game analysis&lt;/h2&gt;

&lt;p&gt;The other feature that took disproportionate effort is the post-game analysis, and it is the feature users write to me about.&lt;/p&gt;

&lt;p&gt;The standard chess-app analysis flow is: play a game, hit “analyse,” watch the engine annotate every move with a depth-15 evaluation. The output is technically correct and almost completely unreadable for anyone below 1800 rating. &lt;em&gt;“You played 18.Re1, computer prefers 18.Bxh6 with eval +1.4.”&lt;/em&gt; Yes, but &lt;em&gt;why?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Chessful’s analysis tries to answer the &lt;em&gt;why&lt;/em&gt; in plain language. It finds the move that lost the game and the threat the user missed, then explains in one or two sentences what was happening structurally. Sometimes it suggests the principle the user should remember, such as &lt;em&gt;“Trades that benefit your opponent’s pawn structure are usually bad even if material is even”&lt;/em&gt;, or &lt;em&gt;“This is a known weak square for the bishop in the Caro-Kann”&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The implementation is a layered model: the engine identifies critical moments, a smaller language model produces the explanation in natural English, and a hand-curated set of pattern detectors flag known motifs (back-rank weakness, isolated queen pawn, knight on rim). Together they produce something that reads like a chess teacher talking.&lt;/p&gt;

&lt;h2 id=&quot;what-chessful-does-not-do&quot;&gt;What Chessful does not do&lt;/h2&gt;

&lt;p&gt;Chessful is not a chess.com replacement. It does not have ranked play, leaderboards, or live human matchmaking. The studio’s deliberate position is that those products exist and are excellent at competitive play, with the world’s best chess infrastructure.&lt;/p&gt;

&lt;p&gt;Chessful is for the player who wants to improve on their own against varied opponents, with explanations they can actually read, on a flight, in a kitchen, or between meetings. It needs no account and no internet, and there is no ranking attached to your name to be embarrassed by.&lt;/p&gt;

&lt;h2 id=&quot;a-small-accidentally-personal-note&quot;&gt;A small accidentally-personal note&lt;/h2&gt;

&lt;p&gt;I’ve never told anyone this in print before, but the reason I made the post-game analysis read like a teacher is that my grandfather was a chess teacher in the Soviet Union before he was anything else. I lost him in 2019. The voice in Chessful’s annotations is, I am told by family who would know, more or less his.&lt;/p&gt;

&lt;p&gt;It’s how the prompts ended up calibrated. If you find the explanations unusually patient, that’s why.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/apps/chessful/&quot;&gt;Chessful&lt;/a&gt; is on the App Store. It is free to try, and premium unlocks unlimited analysis and the full forty-opponent roster. If you’ve been looking for a chess app that explains what you did wrong without making you feel like an idiot, this one might be it.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>On building a native Mac client for App Store Connect</title>
    <link href="https://lagerland-apps.github.io/journal/native-mac-client-for-app-store-connect/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/native-mac-client-for-app-store-connect/</id>
    <published>2026-02-21T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">For most indie developers, App Store Connect is the web app that matters most, and it has been the same web app for ten years. AppMeta is the studio&apos;s least visible app and possibly its most useful one: a native Mac client for the ASC API, made for the day you&apos;re shipping in fourteen locales and need to stop scrolling.</summary>
    <content type="html">&lt;p&gt;App Store Connect, Apple’s web tool for shipping apps, is the web app that matters most in an indie iOS developer’s day. It’s where you manage metadata, push builds to TestFlight, respond to reviews, set pricing, file privacy declarations, and submit for review. Almost every studio I know spends an hour a day in it during ship weeks.&lt;/p&gt;

&lt;p&gt;Underneath, it is a web app from 2014 that has piled on features for a decade. It works. On a long-haul flight, or in a tab next to fifteen others, it is also miserable.&lt;/p&gt;

&lt;p&gt;I built &lt;a href=&quot;/apps/appmeta/&quot;&gt;AppMeta&lt;/a&gt;, a native Mac client, so I could stop being miserable.&lt;/p&gt;

&lt;h2 id=&quot;the-problem-asc-has-specifically&quot;&gt;The problem ASC has, specifically&lt;/h2&gt;

&lt;p&gt;In fairness, App Store Connect’s design constraints are not Apple’s fault. Apple manages the metadata for several million apps across two hundred regions in forty languages, with regulatory edge cases in every market. Building a great web tool on top of all that is hard, and the team behind ASC ships a &lt;em&gt;lot&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;What ASC isn’t optimised for is an indie developer with five to fifty apps shipping across twenty locales. The specific problems:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Localised metadata editing is one locale at a time.&lt;/strong&gt; Editing a description in fourteen languages means switching the locale dropdown fourteen times. There is no side-by-side view.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Keyword fields are 100 characters per locale&lt;/strong&gt;, with no cross-locale gap analysis. Indies find the same keyword waste again in every language because no tool points it out. (The rules for that field, and the folklore around it, now have &lt;a href=&quot;/journal/app-store-keyword-field-100-characters/&quot;&gt;their own post&lt;/a&gt;.)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Review responses are a per-app web flow&lt;/strong&gt; with no inbox. If you have ten apps, you have ten places to check.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Version submission requires a multi-step flow with hidden state.&lt;/strong&gt; “Did I save the export compliance? Did I tick advertising identifier? Did I attach the encryption form?” These have all bitten me. So has forgetting &lt;a href=&quot;/journal/app-store-fields-that-need-a-new-version/&quot;&gt;which fields only change with a new version&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these is catastrophic on its own. Together they are why I had a recurring “App Store Connect” calendar block on Friday afternoons for two years before I shipped AppMeta.&lt;/p&gt;

&lt;h2 id=&quot;what-does-a-native-app-store-connect-client-actually-change&quot;&gt;What does a native App Store Connect client actually change?&lt;/h2&gt;

&lt;p&gt;At its centre, AppMeta is a Mac client that talks directly to the App Store Connect REST API and shows your apps’ metadata side by side. It signs in with an API key you create yourself in App Store Connect; &lt;a href=&quot;/journal/app-store-connect-api-key-setup/&quot;&gt;the key setup guide&lt;/a&gt; walks through that. It changes four things.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Side-by-side localised editing.&lt;/strong&gt; Pick a field and every locale’s version of it is on one screen: the English description, then the German, French, Japanese, and Spanish ones below it, each editable in place. Or pick a locale and edit all of its fields together. Changed fields are marked, and you push when you’re ready. The hour-long localisation pass takes ten minutes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Diff preview before push.&lt;/strong&gt; Before anything is pushed, AppMeta shows exactly what will change against the current live metadata. I trust this feature more than I trust myself, because &lt;em&gt;it caught a typo in five different localisations the day before I would have shipped them.&lt;/em&gt; After that happens to you once, you don’t ship without a diff preview again.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cross-locale keyword analysis.&lt;/strong&gt; AppMeta computes per-character keyword use across every locale and points out wasted space, duplicates, and gaps. I used to keep this in a spreadsheet by hand. Now it’s a panel in the app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reviews in a native list.&lt;/strong&gt; Each app’s reviews, from every storefront, sit in one list you can sort by date or rating, one click away in the sidebar instead of behind ten slow page loads. Pick a review, type a response, send. The response still goes through ASC’s regulated channels, with Apple as the source of truth, but you never leave the Mac.&lt;/p&gt;

&lt;p&gt;There’s also version submission, screenshot management, pricing changes, and a few smaller things. What matters more than the checklist is that &lt;em&gt;every minute of friction the web tool adds&lt;/em&gt; compounds over a year of shipping.&lt;/p&gt;

&lt;h2 id=&quot;why-a-lifetime-price-not-a-subscription&quot;&gt;Why a lifetime price, not a subscription&lt;/h2&gt;

&lt;p&gt;People ask me about this more than anything else about AppMeta, so here is the plain answer.&lt;/p&gt;

&lt;p&gt;App Store Connect tooling is a developer tool, and developer tools have a long history of subscription pricing: JetBrains, Sketch, Figma, Linear. The market would happily pay $19.99 a month for a good ASC client. I considered it.&lt;/p&gt;

&lt;p&gt;I shipped AppMeta as a one-time $29.99 purchase because subscriptions give a tool like this a specific bad incentive. Every month you have to ship enough perceived value to justify the next charge, and that pressure pushes the roadmap toward &lt;em&gt;more features&lt;/em&gt; when it should go toward the right ones. AppMeta’s job is to be a fast, reliable native client, and features added to get through a renewal cycle would make it worse at that.&lt;/p&gt;

&lt;p&gt;A one-time purchase imposes a different discipline. The tool has to be worth $29.99 once, and the next sale has to come from a new user who thinks so, not from a renewal charged to an existing one. Revenue comes in more slowly, and in exchange the design stays honest.&lt;/p&gt;

&lt;h2 id=&quot;what-appmeta-is-not&quot;&gt;What AppMeta is not&lt;/h2&gt;

&lt;p&gt;AppMeta is not a build pipeline tool. It does not replace fastlane, Xcode Cloud, or your CI. It does not generate screenshots; that’s &lt;a href=&quot;/apps/mockly/&quot;&gt;Mockly&lt;/a&gt;’s job. Revenue on the phone is &lt;a href=&quot;/apps/appmeta-pulse/&quot;&gt;AppMeta Pulse&lt;/a&gt;, the iPhone companion.&lt;/p&gt;

&lt;p&gt;It is the native client for the metadata and review side of App Store Connect, the part you spend an hour a day in during ship weeks and the part that needed to stop being miserable.&lt;/p&gt;

&lt;h2 id=&quot;the-short-version&quot;&gt;The short version&lt;/h2&gt;

&lt;p&gt;If you’re an indie iOS or macOS developer shipping in multiple locales and you’ve spent a Friday afternoon flipping through the locale dropdown, &lt;a href=&quot;/apps/appmeta/&quot;&gt;AppMeta&lt;/a&gt; is the studio’s answer: $29.99, one time, lifetime. Demo mode is free if you want to look around before you buy.&lt;/p&gt;

&lt;p&gt;If you’re not an indie developer, this has been twelve hundred words about a niche tool, and you’ve made it admirably far. Thanks for reading. The next post will be about chess.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>How to split a Valentine&apos;s dinner without making it weird</title>
    <link href="https://lagerland-apps.github.io/journal/splitting-a-valentines-dinner-without-making-it-weird/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/splitting-a-valentines-dinner-without-making-it-weird/</id>
    <published>2026-02-14T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">It&apos;s the 14th. Somewhere right now, a group of four friends is staring at a $312 dinner bill, three of them ordered the steak, one ordered the salad, and someone is doing math on a napkin. RightSplit is the app we made for that moment.</summary>
    <content type="html">&lt;p&gt;It is February the 14th. Somewhere in the world right now, a table of four friends is staring at a $312 receipt at the end of a dinner. Three of them had the steak, one had the salad and a glass of wine, and someone is doing math on a napkin.&lt;/p&gt;

&lt;p&gt;This is a small post about that moment and the app I built for it.&lt;/p&gt;

&lt;h2 id=&quot;why-is-split-equally-unfair&quot;&gt;Why is “split equally” unfair?&lt;/h2&gt;

&lt;p&gt;Most splitting tools default to dividing the bill into equal shares. That works when everyone ordered roughly the same things and stops being fair as soon as the orders differ.&lt;/p&gt;

&lt;p&gt;An equal split makes the lighter eater pay for everyone else. The salad-and-wine person at our imaginary table pays $78 for an order closer to $32. They won’t say anything, because the maths is awkward and asking costs more socially than the $46 is worth. They will resent it a little, the next dinner will feel slightly different, and after a year of small inequalities the friendship has lost some trust without anyone being able to say when it happened.&lt;/p&gt;

&lt;p&gt;Item-level splitting fixes this. With the right tool it takes thirty seconds; without one, it takes ten minutes and a calculator.&lt;/p&gt;

&lt;h2 id=&quot;the-splitwise-problem&quot;&gt;The Splitwise problem&lt;/h2&gt;

&lt;p&gt;In the early 2020s most people solved this with Splitwise. It works, but every participant needs an account. The four friends at the table end up signing up for an app that will email them about IOUs for the next eight months because one of them couldn’t be bothered to settle.&lt;/p&gt;

&lt;p&gt;For a recurring group (roommates, a partnership, a regular travel circle) that overhead is fine, even useful. For a one-off Valentine’s dinner with friends, it’s a cost nobody asked to pay.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/apps/rightsplit/&quot;&gt;RightSplit&lt;/a&gt; starts from the other end: &lt;strong&gt;the group should not need to download anything&lt;/strong&gt;. Only the person doing the math has the app.&lt;/p&gt;

&lt;h2 id=&quot;the-flow&quot;&gt;The flow&lt;/h2&gt;

&lt;p&gt;This is how I picture RightSplit doing its job:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The receipt arrives. One person picks up the phone.&lt;/li&gt;
  &lt;li&gt;They take a picture of the receipt. The app reads the items, prices, and tax.&lt;/li&gt;
  &lt;li&gt;They tap each item, then tap the names of the people who had it. A bottle of wine shared by two gets split 50/50, a round of beers shared by three works the same way, and a steak goes to the person who ordered it.&lt;/li&gt;
  &lt;li&gt;The tip is calculated and distributed proportionally (&lt;a href=&quot;/journal/bill-splitting-math-tax-tip-shared-plates/&quot;&gt;the arithmetic, worked all the way out&lt;/a&gt;).&lt;/li&gt;
  &lt;li&gt;The app writes four short messages, one per person, each with the exact amount, plus a pre-filled pay button if the owner has saved a Venmo, PayPal.me, Revolut or Wise handle. The owner sends them in iMessage or WhatsApp.&lt;/li&gt;
  &lt;li&gt;That’s it. The app keeps the split in case the owner wants to look at it later.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That’s the whole product. Nobody gets a shared account, a stream of notifications, or an IOU ledger that follows them around for nine months. The group never has to install RightSplit, and all the effort sits with the person who is already holding the phone.&lt;/p&gt;

&lt;h2 id=&quot;what-item-level-splitting-buys-at-scale&quot;&gt;What item-level splitting buys at scale&lt;/h2&gt;

&lt;p&gt;The design pays off more as groups get bigger.&lt;/p&gt;

&lt;p&gt;For two people, item-level versus equal split rarely matters, because the amounts are small.&lt;/p&gt;

&lt;p&gt;For four people, item-level splitting recovers an average of $20-40 per dinner over an equal split, in favour of whoever ordered modestly. That’s small, but it adds up over a year of group meals.&lt;/p&gt;

&lt;p&gt;For ten people (bachelor parties, family dinners, work outings), the difference between item-level and equal splitting can be $80-150 per person. At that size, an equal split is unfair enough to turn a fun dinner into an awkward Venmo argument the next morning.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/apps/rightsplit/&quot;&gt;RightSplit&lt;/a&gt; Pro+ adds unlimited receipt scans, item-level splitting, uneven splits (the person with the bigger appetite explicitly takes a 1.5× share), unlimited history and Spaces, for $3.99 a year or $7.99 lifetime. The free tier covers equal splits, the tip calculator, your last five splits and your first receipt scan, which is enough for most two-person dinners.&lt;/p&gt;

&lt;h2 id=&quot;a-note-on-small-kindnesses&quot;&gt;A note on small kindnesses&lt;/h2&gt;

&lt;p&gt;Some software exists only to remove a little friction between people, and I think that kind of software is undervalued. Any single split moves very little money. Skipping the awkward conversation about the bill matters more than the money does. Friends remember small kindnesses, and they remember small inequalities even longer.&lt;/p&gt;

&lt;p&gt;If you went out to dinner tonight and someone is staring at a receipt right now, take this as a hint that the math can be easier.&lt;/p&gt;

&lt;p&gt;Happy 14th.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>Reading without a feed: a quiet year with Wikipedia</title>
    <link href="https://lagerland-apps.github.io/journal/reading-without-a-feed/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/reading-without-a-feed/</id>
    <published>2026-02-07T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">I deleted my last social-feed app in late 2024. The hardest part was rebuilding a habit of reading something, anything, in the small windows I used to fill by scrolling. I built WanderWiki mostly to give that habit somewhere to live.</summary>
    <content type="html">&lt;p&gt;Sometime in late 2024 I deleted the last social feed off my phone. I’d like to say it felt clean and freeing, but I spent the next few weeks reaching for the phone, swiping to where the app used to be, finding empty space, and not knowing what to do with the hand or the attention.&lt;/p&gt;

&lt;p&gt;Withdrawal was the easy part. The hard part was that nothing else had been trained to fit the same hole. The five-minute window between meetings, the queue at the coffee shop and the two minutes waiting for the kettle had been algorithmic-feed time for a decade. Without the feed they were just silence. Silence is fine, but a brain that’s been on dopamine for ten years doesn’t yet know what to do with it.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/apps/wanderwiki/&quot;&gt;WanderWiki&lt;/a&gt; is the app in this catalogue I built most directly for that hand and that hole.&lt;/p&gt;

&lt;h2 id=&quot;what-did-i-want-from-a-reading-app&quot;&gt;What did I want from a reading app?&lt;/h2&gt;

&lt;p&gt;The brief I wrote for myself was small. I wanted an app that:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Loaded fast enough to fill a thirty-second window without a loading spinner.&lt;/li&gt;
  &lt;li&gt;Showed me something interesting on first launch without asking what I liked.&lt;/li&gt;
  &lt;li&gt;Got &lt;em&gt;more&lt;/em&gt; interesting if I told it what I liked, &lt;em&gt;without&lt;/em&gt; tracking what I tapped.&lt;/li&gt;
  &lt;li&gt;Worked on a flight without an “offline mode” hidden behind three menus.&lt;/li&gt;
  &lt;li&gt;Didn’t have a feed, or at least didn’t try to be infinite.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Wikipedia was the obvious source. It is the largest collection of well-written, fact-checked, structurally consistent prose in human history, and it’s available under a Creative Commons license. If I couldn’t build a calm reading habit on Wikipedia, the fault would be mine.&lt;/p&gt;

&lt;h2 id=&quot;for-you-without-tracking&quot;&gt;“For You” without tracking&lt;/h2&gt;

&lt;p&gt;Reading apps without a feed run into one problem: pure randomness gets boring quickly. Wikipedia has around seven million English articles, and &lt;a href=&quot;/journal/wikipedia-is-different-in-every-language/&quot;&gt;every language edition is a different encyclopedia&lt;/a&gt;. A truly random tap will give you &lt;em&gt;Italian municipality of 800 people&lt;/em&gt;, &lt;em&gt;American politician (1820-1888)&lt;/em&gt;, and &lt;em&gt;insect taxonomy&lt;/em&gt; in a row, and the user will close the app.&lt;/p&gt;

&lt;p&gt;Most apps solve this by tracking what you read, building a profile, and using it to weight the recommendations. That works, and it’s exactly what I deleted off my phone.&lt;/p&gt;

&lt;p&gt;So can you have &lt;em&gt;For-You-style relevance&lt;/em&gt; without behavioural tracking? WanderWiki’s answer is yes, if you ask the user what they like instead of inferring it. In a one-screen onboarding the user taps interest topics (&lt;em&gt;Science, History, Space, Architecture, Music, Food,&lt;/em&gt; sixteen in all), and the For-You feed draws its articles from the Wikipedia categories behind those declared preferences.&lt;/p&gt;

&lt;p&gt;The user can change the topics any time. What you read or skip doesn’t feed back into what For You picks, and none of it leaves the phone. There is no behavioural model. That makes it &lt;em&gt;less personalised&lt;/em&gt; than a feed-based reader, but easier for the user to correct: if the recommendations go off, the only thing to fix is the list of topics you can see on screen.&lt;/p&gt;

&lt;h2 id=&quot;today-in-history&quot;&gt;Today in History&lt;/h2&gt;

&lt;p&gt;The one piece of editorial scaffolding I did keep is the &lt;strong&gt;Today in History&lt;/strong&gt; view. Switch to it and WanderWiki deals out the notable events that happened on the current calendar date. A treaty in 1648. A first ascent in 1953. A scientific paper in 1979. A peaceful transition of power in 1994.&lt;/p&gt;

&lt;p&gt;It works for the same reason it always has in newspapers: content tied to a date gives the brain a small handhold. It’s &lt;em&gt;this day&lt;/em&gt;, in another year, the same calendar slot occupied by a different version of the world. It’s the feature I get the most direct user feedback on, which is why I kept it.&lt;/p&gt;

&lt;h2 id=&quot;reading-offline&quot;&gt;Reading offline&lt;/h2&gt;

&lt;p&gt;The other constraint I held to was that the app should be some use on a plane.&lt;/p&gt;

&lt;p&gt;Here WanderWiki only partly delivers. A discovery deck is live by nature: Random, For You and Today in History all ask Wikipedia for something new, and on a plane there is no Wikipedia to ask. What WanderWiki does is keep what you save. Save an article on the ground and it is on the phone at cruising altitude, in the same list you use online, with no separate offline mode and no download screen.&lt;/p&gt;

&lt;p&gt;If you want the whole encyclopedia offline, that is a different engineering problem, and &lt;a href=&quot;/alternatives/kiwix/&quot;&gt;Kiwix&lt;/a&gt; solves it. WanderWiki handles the small reading list you build while wandering, which is still there on a 13-hour flight, when a feed replacement is most welcome.&lt;/p&gt;

&lt;h2 id=&quot;what-it-gives-up&quot;&gt;What it gives up&lt;/h2&gt;

&lt;p&gt;A reading app with no feed and no behaviour tracking is not going to outcompete Twitter for attention, and it shouldn’t try. WanderWiki sessions are short, two articles or sometimes three, and they end when the user has had enough. That is intentional, and session length is the one metric where I want WanderWiki to come in below the competition.&lt;/p&gt;

&lt;p&gt;Daily active users is a noisy number for an app like this anyway. The better test is &lt;em&gt;did I just read something the algorithm would not have shown me, and did I close the app before I lost ten minutes I didn’t mean to lose?&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;where-this-fits-in-the-catalogue&quot;&gt;Where this fits in the catalogue&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/apps/wanderwiki/&quot;&gt;WanderWiki&lt;/a&gt; sits alongside a handful of other apps in this privacy-first catalogue that share one idea: the &lt;em&gt;replacement for the feed&lt;/em&gt; doesn’t have to be productive, but it should be calm, finite, and yours.&lt;/p&gt;

&lt;p&gt;It’s a Saturday in early February, and the internet is doing whatever the internet does. If you’ve been looking for something to fill the small windows that used to be filled by something worse, you could do worse than three Wikipedia articles and a quiet kitchen.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Update, 25 October 2026:&lt;/em&gt; WanderWiki has grown since this was written. It now keeps a reading streak, shown on the Profile tab and in a widget, and if you allow notifications it sends one daily reminder, which you can retime or turn off in Settings. The free tier stops at 20 articles a day; WanderWiki Plus swipes without a limit. For You still works from the topics you pick and nothing else.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>I will not ask for your bank login</title>
    <link href="https://lagerland-apps.github.io/journal/i-will-not-ask-for-your-bank-login/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/i-will-not-ask-for-your-bank-login/</id>
    <published>2026-01-31T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">It&apos;s the last day of January and the bank-aggregator apps are advertising themselves into every podcast in America. The pitch is convenience. The price is your read access to your own checking account. AllPaid deliberately skips the bank connection.</summary>
    <content type="html">&lt;p&gt;It is the last Saturday of January. I have just done my own taxes for the year, which is a job I always do badly and never on time. While doing them I noticed that three of the apps on the &lt;em&gt;Productivity&lt;/em&gt; charts of the App Store are bill trackers that connect to your bank. Two of them have grown sharply in the last twelve months. All of them open with the same onboarding flow:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;To get started, please log in to your bank.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;/apps/allpaid/&quot;&gt;AllPaid&lt;/a&gt;, the bill-tracking and subscription-management app this studio ships, does not have that flow and is not going to. This post explains why.&lt;/p&gt;

&lt;h2 id=&quot;what-does-log-in-to-your-bank-actually-do&quot;&gt;What does “log in to your bank” actually do?&lt;/h2&gt;

&lt;p&gt;When a non-bank app asks you to log in to your bank, what happens underneath isn’t quite what most users think. You’re typing your bank password into a third-party screen. That third party is almost always &lt;strong&gt;Plaid&lt;/strong&gt;, occasionally MX or Finicity. The third party stores your credentials or, in newer arrangements, holds an OAuth token issued by your bank. Either way it gets persistent &lt;strong&gt;read access&lt;/strong&gt; to your account: transactions, balances, and often historical statements.&lt;/p&gt;

&lt;p&gt;The app you actually wanted to use then connects to &lt;em&gt;the third party&lt;/em&gt;, not your bank, and pulls a feed of transactions filtered through that aggregator’s models.&lt;/p&gt;

&lt;p&gt;This is the standard architecture of fintech. It’s regulated, and most of the time it works. It also has three properties that users should know about:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Your bank credentials, or a token derived from them, now live somewhere they didn’t live before.&lt;/strong&gt; That somewhere is a target.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The aggregator can see every transaction in your account, in perpetuity, until you revoke access&lt;/strong&gt;, including when the app you signed up for doesn’t need that data.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Aggregators are a business.&lt;/strong&gt; Their growth depends on cross-selling the data they aggregate to other applications, anonymised or otherwise. The anonymisation is sometimes meaningful and sometimes not.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I don’t think aggregators are evil. I do think the convenience tradeoff isn’t priced into the user’s mental model when they tap &lt;em&gt;Continue&lt;/em&gt; on the onboarding screen.&lt;/p&gt;

&lt;h2 id=&quot;what-youre-actually-buying&quot;&gt;What you’re actually buying&lt;/h2&gt;

&lt;p&gt;The promise of bank-linked bill apps is that they will &lt;em&gt;find&lt;/em&gt; your subscriptions and bills automatically. You sign up, give them read access, and a list of recurring charges appears.&lt;/p&gt;

&lt;p&gt;This works, and it is genuinely useful. It is also doing two things, and only one of them is what the user asked for.&lt;/p&gt;

&lt;p&gt;The first is identifying recurring charges, which is the useful part.&lt;/p&gt;

&lt;p&gt;The second is building a picture of &lt;em&gt;every other thing&lt;/em&gt; you spend money on, which you never signed up for and which is the asset the company is actually building. The bill tracking is a pretext for the data pipeline. Some of these companies are open about it (for the ones whose business model is “find subscriptions you forgot about and offer to cancel them”, that is the value exchange). Some are quieter.&lt;/p&gt;

&lt;p&gt;Either way, the user pays with read access to their entire financial life for a feature that comes down to a list they could have written themselves in twenty minutes.&lt;/p&gt;

&lt;h2 id=&quot;the-manual-first-answer&quot;&gt;The manual-first answer&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/apps/allpaid/&quot;&gt;AllPaid&lt;/a&gt; starts from a different premise: most people have somewhere between five and forty recurring bills, and entering them once is not a difficult problem.&lt;/p&gt;

&lt;p&gt;The app is manual-first. You type in your bills, your subscriptions, the rent, the utilities. The app stores them locally on your device, reminds you when they’re due, supports a calendar view, lets you tick them off, and shares specific bills with a partner if needed. With widgets and Siri integration there is almost no daily friction; &lt;em&gt;“Hey Siri, what’s due this week?”&lt;/em&gt; takes one tap. There’s a Pro tier that adds spending analytics and full payment history, also fully on-device.&lt;/p&gt;

&lt;p&gt;What the app does not do, and will not do:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;It does not connect to your bank.&lt;/li&gt;
  &lt;li&gt;It does not connect to a third-party aggregator.&lt;/li&gt;
  &lt;li&gt;It does not have an account system, so there is no login, email collection or profile.&lt;/li&gt;
  &lt;li&gt;It does not see anything you do not type into it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On paper this is less convenient than a Plaid-connected app. In practice the gap is smaller than people expect. Entering everything the first time takes about fifteen minutes if you have a long list. After that, the work is tapping a notification to mark a bill paid, which is the same effort a bank-linked app asks for, at a lower cost.&lt;/p&gt;

&lt;h2 id=&quot;what-this-trades-away&quot;&gt;What this trades away&lt;/h2&gt;

&lt;p&gt;Bank-linked bill apps catch one category of bill that AllPaid will miss: &lt;strong&gt;the subscription you signed up for, forgot about, and would not remember to enter into a manual app&lt;/strong&gt;. The classic “$8.99/month for that streaming service you used twice in 2023.” That is a real benefit, and AllPaid does not offer it.&lt;/p&gt;

&lt;p&gt;If &lt;a href=&quot;/journal/find-every-recurring-charge/&quot;&gt;finding forgotten charges&lt;/a&gt; is the user’s primary need, a bank-linked tool is the better fit, and I’d recommend one. Just know what you are giving up when you connect it.&lt;/p&gt;

&lt;p&gt;Manual-first works for everyone else: people who know roughly what they pay for, want a reminder to pay it, want to share rent with a roommate, want a calendar view of the next thirty days, and don’t want a third party reading their checking account in perpetuity.&lt;/p&gt;

&lt;h2 id=&quot;a-note-on-tax-season&quot;&gt;A note on tax season&lt;/h2&gt;

&lt;p&gt;This post is going up on the 31st of January, and the timing is deliberate. Tax season is when people look at their finances most carefully and most apprehensively. It is also the season when fintech apps run their biggest advertising spend, because conversion is highest when anxiety is highest.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/apps/allpaid/&quot;&gt;AllPaid&lt;/a&gt; is meant to be the calmer answer in that window. It skips the bank login and the anxious onboarding, keeps everything local, and does the boring job of making sure you don’t miss a bill or pay a late fee. It’s free, with Pro at $1.99 a month, $12.99 a year, or $24.99 lifetime, so no subscription is required.&lt;/p&gt;

&lt;p&gt;If this is the year you stop trading read access to your bank for features you could write down yourself, we think you’re right.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>Building a sleep app for nurses, pilots, and the people who don&apos;t have a 9-to-5</title>
    <link href="https://lagerland-apps.github.io/journal/building-a-sleep-app-for-night-shifts/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/building-a-sleep-app-for-night-shifts/</id>
    <published>2026-01-24T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Most sleep apps assume an 11pm bedtime and a 7am alarm. The people who keep hospitals, planes, and emergency rooms running don&apos;t live that way. AfterShift is the app I built after hearing the same complaint from too many friends in scrubs.</summary>
    <content type="html">&lt;p&gt;A friend who works ICU nights asked me, in 2024, why none of her sleep apps understood what she was doing.&lt;/p&gt;

&lt;p&gt;She’d open one of the popular ones, log a five-hour daytime sleep, and the app would politely tell her she’d had a &lt;em&gt;poor night&lt;/em&gt; and should try going to bed earlier. The app meant well. Its model of a human was someone who sleeps at night. Her model of a human was a nurse who sleeps when the rotation allows.&lt;/p&gt;

&lt;p&gt;That conversation was the start of &lt;a href=&quot;/apps/aftershift/&quot;&gt;AfterShift&lt;/a&gt;. This is what I learned building it.&lt;/p&gt;

&lt;h2 id=&quot;why-is-the-9-to-5-assumption-everywhere-in-sleep-apps&quot;&gt;Why is the 9-to-5 assumption everywhere in sleep apps?&lt;/h2&gt;

&lt;p&gt;Open any major consumer sleep app and walk through onboarding. You’ll be asked when you go to bed, when you wake up, and what your weekend pattern is. The app assumes a five-day workweek with weekends free, and it assumes “night” means one uninterrupted block of darkness.&lt;/p&gt;

&lt;p&gt;Now take a typical nurse’s twelve-hour rotation: three days on, three days off, a two-week cycle, with days flipping to nights halfway through. Her sleep windows might be 10pm-6am one week and 9am-3pm the next, with a chaotic transition night in between. The sleep app’s model breaks, its recovery scores make no sense, and its caffeine recommendations actively harm her. (Most rosters like hers are variations on a handful of named patterns; &lt;a href=&quot;/journal/rotating-shift-schedules-explained/&quot;&gt;rotating shift schedules explained&lt;/a&gt; lays out DuPont, 2-2-3 and the rest, and which are hardest on sleep.)&lt;/p&gt;

&lt;p&gt;This is a real population. The US has about 4 million registered nurses and several hundred thousand commercial pilots, plus paramedics, firefighters, police, factory workers, refinery operators, and a long tail of other rotating-shift workers. Generic sleep apps serve none of them well.&lt;/p&gt;

&lt;h2 id=&quot;what-shift-aware-means-in-practice&quot;&gt;What “shift-aware” means in practice&lt;/h2&gt;

&lt;p&gt;The first difference between AfterShift and generic apps is &lt;em&gt;what counts as a sleep session&lt;/em&gt;. AfterShift accepts:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A primary sleep block of any length, at any time of day, on any day.&lt;/li&gt;
  &lt;li&gt;Optional naps before or after the primary block. Pre-shift naps are a recognised fatigue countermeasure for night work, and post-shift “anchor sleeps” before transitioning back to days are another.&lt;/li&gt;
  &lt;li&gt;Fragmented patterns. A six-hour sleep broken once is structurally different from an unbroken six hours, and the app treats it that way.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The second is the &lt;strong&gt;Shift Recovery Score&lt;/strong&gt;, the metric I’m proudest of. It isn’t a sleep score in the consumer sense. It’s a forward-looking estimate: given the sleep you’ve had since your last shift, the rotation pattern you’re on, and how fragmented your recent sleep has been, &lt;em&gt;how recovered are you for the next block?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It’s calibrated against shift-work fatigue research, not the average iPhone user’s resting heart rate. A 7-hour daytime sleep before a night shift can score higher than an 8-hour night sleep before a day shift, because the first one sets you up for the coming work block and the second is misaligned with it. Generic sleep apps penalise the daytime sleep and reward the night sleep, which is backwards for this user.&lt;/p&gt;

&lt;h2 id=&quot;caffeine-timing-deserves-a-whole-feature&quot;&gt;Caffeine timing deserves a whole feature&lt;/h2&gt;

&lt;p&gt;The other surprise in building AfterShift was how much research exists on caffeine timing for shift workers, and how little of it reaches consumer apps.&lt;/p&gt;

&lt;p&gt;The short version: caffeine has a half-life of about five hours. A coffee three hours before bed leaves enough in your system to disrupt sleep onset and sleep architecture. A coffee at the start of a night shift keeps you alert when you least want it, at 9am when you finally try to sleep. The right strategy depends on which way your shift is rotating, and most shift workers work it out through years of trial and error.&lt;/p&gt;

&lt;p&gt;AfterShift builds the strategy in. Tell the app your upcoming shift block and it gives you the latest sensible caffeine cutoff that still protects your post-shift sleep. It’s not glamorous, but going by user feedback it is the most-mentioned feature. The rest of the routine for the day after a night shift, from blackout shades to the nap before the next one, is in &lt;a href=&quot;/journal/how-to-sleep-after-a-night-shift/&quot;&gt;how to sleep after a night shift&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;what-it-takes-off-the-users-plate&quot;&gt;What it takes off the user’s plate&lt;/h2&gt;

&lt;p&gt;I also underestimated how much &lt;em&gt;administrative load&lt;/em&gt; shift workers carry around their own sleep. Knowing when you slept and when your next shift starts, working out recovery in your head, deciding whether you need a nap: all of it runs in the background of their day, on top of the job itself.&lt;/p&gt;

&lt;p&gt;AfterShift takes that over. Calendar shift import handles the schedule (most large employers publish rotations to a calendar feed nurses can subscribe to). Sleep windows are planned from the shift times, actual sleep is read from Apple Health, and the caffeine timing updates automatically when shifts change. The user doesn’t have to keep doing the math.&lt;/p&gt;

&lt;p&gt;With the math gone, the mental load drops, and with less load, people sleep better. I didn’t predict that second-order effect.&lt;/p&gt;

&lt;h2 id=&quot;who-it-isnt-for&quot;&gt;Who it isn’t for&lt;/h2&gt;

&lt;p&gt;AfterShift isn’t a general sleep tracker. If you have a stable 9-to-5 schedule, &lt;a href=&quot;/apps/observa/&quot;&gt;Observa&lt;/a&gt; is the better fit from the studio: it interprets all your Apple Health data, with sleep as one of the categories. AfterShift is for people whose schedule is the problem.&lt;/p&gt;

&lt;p&gt;It is also not a clinical tool. Sleep disorders such as narcolepsy and sleep apnoea need a sleep clinic. AfterShift’s Shift Recovery Score is informational and not a diagnosis. I’d rather lose users to a real doctor than oversell what consumer software can do.&lt;/p&gt;

&lt;h2 id=&quot;why-we-built-it&quot;&gt;Why we built it&lt;/h2&gt;

&lt;p&gt;A whole category of work keeps modern infrastructure running (healthcare, transport, public safety, manufacturing), and consumer software has mostly designed around the people who do it. &lt;a href=&quot;/apps/aftershift/&quot;&gt;AfterShift&lt;/a&gt; was an experiment in designing &lt;em&gt;for&lt;/em&gt; them, starting from the assumption that their schedule is the normal life of millions of people and not a deviation from it.&lt;/p&gt;

&lt;p&gt;If you work nights, rotations, or anything else that breaks the 9-to-5 mould, the app is on the App Store. And if you know a nurse, pilot, or paramedic who has been putting up with a generic sleep tracker, send them the link.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>Your Apple Health data isn&apos;t telling you what you think it&apos;s telling you</title>
    <link href="https://lagerland-apps.github.io/journal/your-apple-health-data-doesnt-mean-what-you-think/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/your-apple-health-data-doesnt-mean-what-you-think/</id>
    <published>2026-01-17T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Three years of HRV charts, ten thousand data points, and a feeling that none of it added up to anything. The story behind Observa, and why interpreting health data matters more than tracking it.</summary>
    <content type="html">&lt;p&gt;I have worn an Apple Watch since 2018. By the time I started building &lt;a href=&quot;/apps/observa/&quot;&gt;Observa&lt;/a&gt;, Apple Health had eight years of my data: sleep, heart rate, HRV, ECG readings, mindfulness minutes, workout sessions, blood oxygen, walking steadiness, the lot.&lt;/p&gt;

&lt;p&gt;I had no idea what any of it meant.&lt;/p&gt;

&lt;p&gt;I mean that literally. I could open the Health app, watch a number go up and down, look at a chart shaped like a small mountain range, and still not answer the only question that mattered: &lt;em&gt;should I do anything differently this week?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Observa exists to answer that question.&lt;/p&gt;

&lt;h2 id=&quot;what-is-apple-health-good-at&quot;&gt;What is Apple Health good at?&lt;/h2&gt;

&lt;p&gt;Apple Health is excellent at what it’s built for. It collects, normalises, and stores health metrics with privacy guarantees no other consumer system has offered. The charts are well designed, the unit handling is careful, and the data layer is, honestly, the best in the industry.&lt;/p&gt;

&lt;p&gt;What Apple Health doesn’t try to do, and in my view shouldn’t, is editorialise. It won’t tell you that your HRV dropped because of last week’s two short nights. It won’t connect your morning resting heart rate to the wine you drank on Saturday. It won’t say, “your training load is twenty percent above your eight-week average and your recovery scores are dropping; consider a deload week.” Apple is right to hold back here. Health data is sensitive, and over-interpretation is a real danger.&lt;/p&gt;

&lt;p&gt;For the user, though, that restraint leaves a gap: you have the data and nothing that tells you what it means.&lt;/p&gt;

&lt;h2 id=&quot;the-chart-trance-problem&quot;&gt;The chart-trance problem&lt;/h2&gt;

&lt;p&gt;If you’ve ever spent twenty minutes scrolling through a year of HRV measurements looking for a pattern, you know the problem I mean. The brain is bad at spotting patterns in noisy time series. We see trends that aren’t there and miss ones that are. We anchor on the latest measurement. One low reading makes us anxious and one high reading reassures us, and statistically neither means anything.&lt;/p&gt;

&lt;p&gt;More willpower won’t fix this, because the problem is the &lt;em&gt;display&lt;/em&gt;. A chart with seven hundred data points and no overlay works more like a Rorschach test than a tool.&lt;/p&gt;

&lt;h2 id=&quot;what-observa-does&quot;&gt;What Observa does&lt;/h2&gt;

&lt;p&gt;Observa sits on top of Apple Health and answers a small set of questions directly:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;What variable is most correlated with your sleep quality this month?&lt;/strong&gt; Maybe it’s training volume. Maybe it’s screen time before bed. Maybe it’s the day of the week (don’t underestimate Sunday-night anxiety as a predictor).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;What does your HRV trend look like, normalised against your own baseline?&lt;/strong&gt; Your baseline, not the population’s. A 38 ms HRV reading means nothing until you know whether your personal baseline is 32 or 56.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Which days in the last 90 deviated most from baseline, and what else changed on those days?&lt;/strong&gt; This is where the interesting stories are, the ones where you say “oh, of course, that was the week I flew through three time zones.”&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Is your training load keeping pace with your recovery, or are the two diverging?&lt;/strong&gt; If they diverge, you are building up fatigue, however the individual workouts felt.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of this is a medical diagnosis. Observa can’t tell you whether you have a clinical sleep disorder, a cardiac issue, or an autoimmune condition, and it won’t pretend to. What it can do is take a year of your own data and turn it into the three or four sentences a thoughtful coach might give you if they had time to read it carefully, which most coaches don’t.&lt;/p&gt;

&lt;h2 id=&quot;why-this-had-to-be-on-device&quot;&gt;Why this had to be on-device&lt;/h2&gt;

&lt;p&gt;The other constraint behind Observa is the obvious one: health data should never leave your device.&lt;/p&gt;

&lt;p&gt;That’s a statement of values, and it’s also a technical decision with real consequences for the product. A cloud version of Observa could use better correlation models, larger datasets, and more compute. It would also be a target for breaches, a regulatory minefield in several jurisdictions, and, worst of all, something the user couldn’t verify.&lt;/p&gt;

&lt;p&gt;Observa’s correlation analysis runs on the device, using local models small enough to fit in the app bundle. The analyses are simpler than what a cloud service could do. In return, nobody but you ever sees a single data point. There is no cloud account to compromise, no employee with database access, and no future press release about having “accidentally trained a model on your sleep data.”&lt;/p&gt;

&lt;p&gt;I think that’s the right tradeoff for health data. I know not everyone agrees, and for some uses, such as clinical research and longitudinal population studies, on-device can’t compete. Observa isn’t built for those. It’s the &lt;em&gt;interpretation layer&lt;/em&gt; for one person’s own life, and that person owns it.&lt;/p&gt;

&lt;h2 id=&quot;what-this-means-in-practice&quot;&gt;What this means in practice&lt;/h2&gt;

&lt;p&gt;If you keep opening the Health app, scrolling, and coming away with nothing, &lt;a href=&quot;/apps/observa/&quot;&gt;Observa&lt;/a&gt; was made for you. It reads what’s already in your Health database (with your permission, limited to the categories you allow) and gives you a weekly read in place of a panel of charts.&lt;/p&gt;

&lt;p&gt;It won’t tell you what to eat or when to sleep. Now and then it will tell you something specific and useful, like “your resting heart rate has been elevated for three weeks and the most likely correlate is training volume,” and leave the decision to you.&lt;/p&gt;

&lt;p&gt;That’s the whole product: Apple’s data layer plus a thin layer of honest interpretation. It has no tracking, no upload, and no account, and it gives no medical advice. It does the modest, useful job the Health app leaves undone.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>A streak counter is a debt the user owes the app</title>
    <link href="https://lagerland-apps.github.io/journal/streaks-are-a-debt/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/streaks-are-a-debt/</id>
    <published>2026-01-10T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Last week&apos;s post was the polite version. This is the structural one: streak counters are a debt instrument. The app issues them, the user owes them, and the app collects on the missed day. Here is why Taskful Day was built without one.</summary>
    <content type="html">&lt;p&gt;Last Saturday’s post made the polite case against guilt-driven fitness apps. This week’s is the structural one, and it’s a specific argument about &lt;a href=&quot;/apps/taskful-day/&quot;&gt;Taskful Day&lt;/a&gt;, the daily planner this studio ships.&lt;/p&gt;

&lt;h2 id=&quot;what-is-a-streak-counter-actually&quot;&gt;What is a streak counter, actually?&lt;/h2&gt;

&lt;p&gt;A streak counter looks like a positive number. The app tells you: &lt;em&gt;seven days in a row&lt;/em&gt;. &lt;em&gt;Twenty-eight days in a row&lt;/em&gt;. &lt;em&gt;One hundred and forty-three days in a row&lt;/em&gt;. The number goes up, and it feels like a reward.&lt;/p&gt;

&lt;p&gt;The same counter has a second behaviour, and that one drives the engagement loop: on a miss, it resets to zero. Not to &lt;em&gt;N − 1&lt;/em&gt;. To zero.&lt;/p&gt;

&lt;p&gt;That asymmetry is what makes a streak work as a growth lever, and it’s also what makes it a debt instrument dressed up as a reward.&lt;/p&gt;

&lt;p&gt;A 143-day streak on screen doesn’t say “you’ve earned this.” It says “if you don’t open me tomorrow, you owe me 143 days.” The number is denominated in &lt;em&gt;future panic&lt;/em&gt;. Each additional day inflates the debt, and the longer the streak, the more painful the reset and the more hostage-y the relationship.&lt;/p&gt;

&lt;p&gt;Apps know this and build it on purpose. Every meditation app, language app, and habit tracker shipped a streak counter the moment Snapchat showed it worked. Designers don’t add it because users want it. Users &lt;em&gt;don’t&lt;/em&gt; want to lose it, and that reluctance is exactly what gets the app opened.&lt;/p&gt;

&lt;h2 id=&quot;the-ratchet-effect&quot;&gt;The ratchet effect&lt;/h2&gt;

&lt;p&gt;Streaks do something else that might be worse than the obvious cost.&lt;/p&gt;

&lt;p&gt;Once a long streak exists, the user starts behaving worse to protect it. They open the app at midnight to log a fake meditation, mark a task complete that they didn’t do, walk circles in the kitchen to hit the daily steps, or train through an injury they should be resting.&lt;/p&gt;

&lt;p&gt;The number &lt;em&gt;the app shows as proof of progress&lt;/em&gt; makes them do less of the actual progress. This is Goodhart’s Law in two taps. The streak stops measuring consistency and starts measuring “willingness to lie to the app to avoid the pain of resetting.”&lt;/p&gt;

&lt;p&gt;If your tool’s headline number rewards users for behaviour they’ll be ashamed of later, you’ve built a dependency, and calling it a tool doesn’t change that.&lt;/p&gt;

&lt;h2 id=&quot;the-taskful-day-alternative&quot;&gt;The Taskful Day alternative&lt;/h2&gt;

&lt;p&gt;When I designed &lt;a href=&quot;/apps/taskful-day/&quot;&gt;Taskful Day&lt;/a&gt;, I skipped “should we have a streak?” and asked “what does the app show where the streak would normally go?”&lt;/p&gt;

&lt;p&gt;Nothing, it turned out.&lt;/p&gt;

&lt;p&gt;The home screen shows today’s plan and today only. Yesterday’s incomplete tasks aren’t marked red or scolded. They come back as &lt;strong&gt;follow-ups&lt;/strong&gt;, a small prompt that says, in effect, “this is something you said you wanted to do; tap to bring it to today, or dismiss it.” The user decides. The app doesn’t comment on whether yesterday was a “good day” or a “bad day.”&lt;/p&gt;

&lt;p&gt;There’s a reflection view and a focus-session timer if you want them, and neither turns into a punishment system. The app doesn’t know whether you had a productive day, and it shouldn’t pretend to.&lt;/p&gt;

&lt;p&gt;The cost is a weaker “open the app every single day or else” loop, so daily-active-user numbers are lower than they would be with a streak. I know because I built a prototype with a streak counter, watched the engagement curve, and turned it off anyway.&lt;/p&gt;

&lt;h2 id=&quot;what-it-buys&quot;&gt;What it buys&lt;/h2&gt;

&lt;p&gt;What the design buys is something I think of as &lt;strong&gt;week-three trust&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When a user opens Taskful Day for the first time in five days, the app doesn’t yell at them. There’s no flame, no “you broke your streak,” and no catch-up modal. Today’s plan is there, and they can use it or not.&lt;/p&gt;

&lt;p&gt;Most users in that situation mention the same thing in feedback: relief. Every other planner had trained them to expect punishment, and when it doesn’t come, they open the app the next day. Not being a guilt machine turns out to be a retention strategy too, just a slower one.&lt;/p&gt;

&lt;p&gt;I don’t think Taskful Day will ever match the daily-active-user numbers of a streak-driven planner, and I’m fine with that. The users it keeps use it the way it’s meant to be used, as a tool that meets them where they are and not a counter they’re chained to.&lt;/p&gt;

&lt;h2 id=&quot;the-position-plainly&quot;&gt;The position, plainly&lt;/h2&gt;

&lt;p&gt;Streak counters work for the app. They’re brittle and punishing, they corrupt the metric they claim to measure, and they teach users to lie to their tools. Refusing them has a small craft cost and a real product cost, and both are worth paying.&lt;/p&gt;

&lt;p&gt;If you want a planner that doesn’t keep score against you, &lt;a href=&quot;/apps/taskful-day/&quot;&gt;Taskful Day&lt;/a&gt; is what this studio offers.&lt;/p&gt;

&lt;p&gt;If you want a streak app that respects you, there isn’t one, because the streak is what stops it from respecting you.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>If your fitness app is making you feel guilty in week one, that&apos;s the design, not you</title>
    <link href="https://lagerland-apps.github.io/journal/resolutions-and-the-fitness-app-trap/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/resolutions-and-the-fitness-app-trap/</id>
    <published>2026-01-03T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Forty-eight hours into the new year, the fitness apps are already doing what they were built to do: rewarding you for one good day, then twisting the knife the day after. A short note on why most of them are designed wrong, and what to look for in the ones that aren&apos;t.</summary>
    <content type="html">&lt;p&gt;It’s the third of January and the fitness apps are already doing the thing.&lt;/p&gt;

&lt;p&gt;The thing starts with a gentle, well-designed, nicely typeset push notification saying you missed your goal by &lt;em&gt;just a little&lt;/em&gt;, which is a shame, but you can still recover if you log in &lt;em&gt;right now&lt;/em&gt;. After that comes a streak counter that resets if you don’t open the app for two days, a leaderboard against three friends you haven’t seen since college, a coach character with a frowning face, and a colour change from green to amber to red as the days slip.&lt;/p&gt;

&lt;p&gt;I’m not making fun of these apps. Talented people design them, the typography and animations are good, and they convert. They are doing exactly what their growth dashboards reward. They are not helping you train.&lt;/p&gt;

&lt;h2 id=&quot;the-mechanism&quot;&gt;The mechanism&lt;/h2&gt;

&lt;p&gt;If a fitness app has ever turned on you in week two, this is what was happening on the engineering side:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;You signed up because you wanted to do something more consistently.&lt;/li&gt;
  &lt;li&gt;The app measured “consistency” with a streak counter, a single integer that resets to zero on any miss.&lt;/li&gt;
  &lt;li&gt;Streaks are sticky in the short term. People do open the app to keep them alive.&lt;/li&gt;
  &lt;li&gt;Streaks are also brittle: miss one day and the counter resets. The app’s growth team knows this, and it’s why streaks work. The fragility keeps you opening the app.&lt;/li&gt;
  &lt;li&gt;So when you miss day four, the app punishes you, you feel bad, and one of two things happens. You panic-open and log a fake workout to save the streak, or you slide into feeling bad and quietly stop opening the app for the rest of the year.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You didn’t train in either case. One is theatre and the other is a churned user. Both feel like the app’s fault, and they kind of are.&lt;/p&gt;

&lt;h2 id=&quot;what-does-a-non-hostile-fitness-app-look-like&quot;&gt;What does a non-hostile fitness app look like?&lt;/h2&gt;

&lt;p&gt;A handful of design choices reliably mark an app that will still treat you well in week three:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;No streak counter on the home screen.&lt;/strong&gt; If there is one, it doesn’t reset to zero. It counts total days trained over your lifetime and never goes down, so missing Tuesday costs you nothing.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Follow-ups for missed work.&lt;/strong&gt; Tasks or workouts that didn’t happen yesterday aren’t punished or marked red. The app offers them to you again today. They roll forward and nothing resets.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;No comparison with people you didn’t choose.&lt;/strong&gt; Leaderboards are off by default, and there are no friends whose routines you’re pushed to compete with.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Notifications that explain themselves.&lt;/strong&gt; “You haven’t logged in three days” is hostile. “Your last lifting session was Thursday. Here’s the program for tomorrow if you want it” uses the same data and treats you like an adult.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;A way to leave for a week without losing your data.&lt;/strong&gt; People go on holiday, get injured, get busy. The app should be where you left it when you come back.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;what-this-studio-ships&quot;&gt;What this studio ships&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/apps/taskful-day/&quot;&gt;Taskful Day&lt;/a&gt; is a daily planner with no streak counter, flame, or red X. Unfinished tasks roll forward to tomorrow. There is a focus-session timer and a reflective view if you want them, and nothing pretends to know whether you had a “good day” or a “bad day.”&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/apps/gymlogger-x/&quot;&gt;GymLogger X&lt;/a&gt; is a strength-training log without a social feed, leaderboard, or streak guilt. It tracks sets, reps, PRs, and 1RM trends. If you skip a week, the app does not turn red.&lt;/p&gt;

&lt;p&gt;Fitness apps don’t have to be flat and joyless. Pacing and motivation take real craft, and so does the small celebration when you hit a personal record. My complaint is with a baseline that runs on guilt. A celebration should come from what the user achieved, and the app shouldn’t squeeze it out of them by punishing the rest of their life.&lt;/p&gt;

&lt;h2 id=&quot;a-small-ask-for-the-third-of-january&quot;&gt;A small ask for the third of January&lt;/h2&gt;

&lt;p&gt;If you set yourself a fitness target for 2026, the most useful advice I have is to &lt;strong&gt;pick the app that treats you well in week three over the one that converts hardest in week one&lt;/strong&gt;. They are usually different apps, and the second kind will hurt you in February.&lt;/p&gt;

&lt;p&gt;That’s the whole post. Go for a walk, lift something, and don’t let the streak counter run your life.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>What I&apos;m not doing in 2026</title>
    <link href="https://lagerland-apps.github.io/journal/not-doing-in-2026/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/not-doing-in-2026/</id>
    <published>2026-01-01T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">It&apos;s the first day of the year, and all over the internet people are listing what they will build, ship, optimize, and grow. This is a shorter list: what this studio is choosing not to do.</summary>
    <content type="html">&lt;p&gt;It’s the first day of 2026. Developers everywhere have started publishing their roadmaps for the year, a pleasant tradition, and I’m sure most of them are sincere.&lt;/p&gt;

&lt;p&gt;I’d like to do the opposite and list what I am &lt;strong&gt;not&lt;/strong&gt; doing this year.&lt;/p&gt;

&lt;h2 id=&quot;not-adding-a-single-advertising-sdk&quot;&gt;Not adding a single advertising SDK&lt;/h2&gt;

&lt;p&gt;Lagerland Apps has zero third-party tracking SDKs across the entire catalogue. That means no analytics, no advertising networks, and no “anonymized” telemetry that quietly fingerprints people. It won’t change in 2026, and an attractive revenue share offer won’t change it either. The day I add an ads SDK, the studio’s whole positioning falls apart.&lt;/p&gt;

&lt;h2 id=&quot;not-chasing-a-ten-app-year&quot;&gt;Not chasing a ten-app year&lt;/h2&gt;

&lt;p&gt;The catalogue today is fourteen apps. I don’t need a fifteenth, sixteenth, or twentieth. The studio is one person, and fourteen apps is already about as many as one person can support properly. If I ship a new app this year, it will be because the idea is good enough to displace something else, and not because the calendar said it was time.&lt;/p&gt;

&lt;h2 id=&quot;not-turning-anything-into-a-daily-engagement-product&quot;&gt;Not turning anything into a daily-engagement product&lt;/h2&gt;

&lt;p&gt;Several of the apps would look more “successful” by App Store metrics if I added streaks, daily notifications, badges, or social comparison. Taskful Day would convert harder with a streak counter. AfterShift would retain more users with a daily nag. I’m not doing any of that. I’d rather have a smaller userbase that doesn’t resent me.&lt;/p&gt;

&lt;h2 id=&quot;not-chasing-ai-features-for-ais-sake&quot;&gt;Not chasing AI features for AI’s sake&lt;/h2&gt;

&lt;p&gt;I expect the most disagreement on this one. I use language models in my own workflow, and I think they’re useful. Where AI really earns a place in an app, I’ll add it: Observa’s plain-language interpretation of HRV is one example, and Chessful’s mistake explanations are another. But a “tap here to summarize your day with AI” button that changes nothing is noise, and I’d rather ship no AI feature than a fashionable one.&lt;/p&gt;

&lt;h2 id=&quot;not-raising&quot;&gt;Not raising&lt;/h2&gt;

&lt;p&gt;There is no funding round in the plans for 2026, and I don’t need one. The studio is small, the apps are profitable, and investors in a one-person operation would bring ambitions that don’t fit. The honest version of “we’re not raising right now” is “we don’t want to.”&lt;/p&gt;

&lt;h2 id=&quot;not-going-dark&quot;&gt;Not going dark&lt;/h2&gt;

&lt;p&gt;I’m also not disappearing. This journal is new, and I plan to write more honestly through 2026 than in any previous year, including when things go wrong, which they will. Expect shipping notes, rebrand stories, post-mortems on pricing experiments, and short essays about why a particular feature exists. I’ll write when there’s something worth saying, not on a content-marketing schedule.&lt;/p&gt;

&lt;h2 id=&quot;what-does-this-mean-for-the-apps-in-2026&quot;&gt;What does this mean for the apps in 2026?&lt;/h2&gt;

&lt;p&gt;If you already use the apps, what’s coming in 2026 is more of the same: refinements over additions, the same privacy posture, and the same one-time-or-honest-freemium pricing. New apps that ship this year will face a high bar, so there won’t be many of them. I’m fine with that.&lt;/p&gt;

&lt;p&gt;If that’s the kind of studio you want software from, you’re in the right place. If you want a studio that ships fifteen new features a quarter and live-streams its OKRs, there are several excellent ones (I mean that), but this isn’t one of them.&lt;/p&gt;

&lt;p&gt;Welcome to 2026.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Update, 25 October 2026: two of these didn’t hold. The catalogue grew this year instead of staying at fourteen, and three apps now have a streak of some kind: EarnLock (a step-goal streak with a weekly rest day), Millrace (extra undos at daily-streak milestones), and WanderWiki (a reading streak with an optional daily reminder). Taskful Day and AfterShift still have none.&lt;/em&gt;&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>What this journal is, and what it is not</title>
    <link href="https://lagerland-apps.github.io/journal/welcome/" rel="alternate" type="text/html"/>
    <id>https://lagerland-apps.github.io/journal/welcome/</id>
    <published>2025-12-27T00:00:00+00:00</published>
    <updated>2026-10-26T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">A short note on why Lagerland Apps now has a journal, and what you can expect to find here.</summary>
    <content type="html">&lt;p&gt;Lagerland Apps is a one-person studio shipping iOS and macOS apps (14 when this post went up, 20 today). Until now, the website has been app-page-first: you land on an app, learn about it, and install it. That’s still the goal, but some stories are too broad for a single app page, and this journal is for those.&lt;/p&gt;

&lt;h2 id=&quot;what-is-the-lagerland-apps-journal&quot;&gt;What is the Lagerland Apps journal?&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Rebrand stories.&lt;/strong&gt; When an app gets a new identity, a new direction, or a new home, the details matter. Soon. was formerly TheWait. AppMeta started as a side-tool and became a full-time project. I’d like to document these transitions for the people who use the apps and the people who are curious about how indie iOS studios actually work.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Shipping notes.&lt;/strong&gt; Short changelog entries that go further than an App Store “What’s New” line: design decisions, why a feature exists, why another one was cut, with the actual reasoning behind them.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Principles.&lt;/strong&gt; Occasional essays on privacy-first design, honest monetization, and what it looks like to build apps without advertising incentives. These appear only when I have something worth saying.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;what-is-this-journal-not&quot;&gt;What is this journal not?&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;A marketing blog.&lt;/strong&gt; I’m not chasing SEO keywords or publishing on a schedule for algorithmic reasons. Posts arrive when there’s something real to document.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;A dev blog full of Swift tips.&lt;/strong&gt; The apps are built with SwiftUI, HealthKit, StoreKit, and Apple’s frameworks, but if you want Swift tutorials, there are better sources.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;An AI-generated content farm.&lt;/strong&gt; Every post here is written by &lt;a href=&quot;/lagerland-apps/&quot;&gt;one independent developer&lt;/a&gt;, because the whole point of this studio is that one person makes all the decisions.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;how-to-read-along&quot;&gt;How to read along&lt;/h2&gt;

&lt;p&gt;The &lt;a href=&quot;/journal/&quot;&gt;journal index&lt;/a&gt; lists every post in reverse chronological order. There are no social widgets, comments, or newsletter sign-up wall. If you want to get in touch, &lt;a href=&quot;mailto:lagerland.apps@proton.me&quot;&gt;email me&lt;/a&gt;. If you want to support the work, &lt;a href=&quot;/apps/&quot;&gt;download an app you’d actually use&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Welcome.&lt;/p&gt;
</content>
  </entry>

</feed>
