<?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-21T00: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 least glamorous setting in a training log and the one that decides session length. 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;Two rules sit under that table. 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 it 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 shifted from fixed prescriptions toward a looser picture: rest 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 its size and its length. Twenty-one people for eight weeks can show a difference; it 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, but 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;Because 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’ conclusion was that volume load, not the rest interval, drove the growth.&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;The practical version is simple. 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;&lt;strong&gt;Cut rest on isolation and machine work first.&lt;/strong&gt; 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;&lt;strong&gt;Pair opposing exercises.&lt;/strong&gt; 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;&lt;strong&gt;Rest less and add a set.&lt;/strong&gt; Longo’s volume-matched conditions are the evidence that 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, for a reason that 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 the variable fixed. It also stops rest creeping the other way on days when you are in a hurry.&lt;/p&gt;

&lt;p&gt;This is training information, 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-25T00: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 – 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 – 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 – 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 – 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 – 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 – 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 – 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 – 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 – 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 – 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 – 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 – 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 the promise is the 45 days, not the Thursday. 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-25T00: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 honest state of the evidence is a consensus of coaches, a large survey of athletes and a small number of controlled trials. That is enough to give 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. Here is what the research and the people who coach for a living say.&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-09T00: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 80 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. Here is 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;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 80 has a word on the playing field. There is no tutorial screen, no hand icon and no arrow. The puzzle had to teach the rule, the hidden weights and the cards that reveal them by itself. 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 all 80 levels:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Every known weight states its value twice&lt;/strong&gt;, 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;/li&gt;
  &lt;li&gt;&lt;strong&gt;A full but wrong board shudders once&lt;/strong&gt;: a damped 1.2° shake over half a second, with a soft haptic. No red, no buzzer, no failure screen. A drop that misses every hook isn’t even that; the piece glides back to its slot.&lt;/li&gt;
&lt;/ul&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. Instead, 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;&lt;strong&gt;Live tilt preview.&lt;/strong&gt; 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;&lt;strong&gt;A teaching line, on levels 1 to 5 only.&lt;/strong&gt; 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;&lt;strong&gt;A short introduction for each kind of card.&lt;/strong&gt; 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:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Size:&lt;/strong&gt; the “?” bubble is one fixed size.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Sound:&lt;/strong&gt; with Sound on, each weight has its own note, and heavier is lower. A “?” makes an unpitched thud.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Touch:&lt;/strong&gt; a “?” always gives the same haptic strength.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Speech:&lt;/strong&gt; VoiceOver calls it “hidden teal drop” and never says a number, and its beam “cannot settle, hidden weight”.&lt;/li&gt;
&lt;/ul&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. 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: same meaning, no 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 hold this to account. 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 isn’t wordless everywhere. Settings, the four chapter names (The Hang, The Secret, The Cascade, The Exhibition), the four world names and the unlock screen use words. 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;The canvas is held to its rule by a test that reads the code drawing 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 an English game inside a store listing written in 50 locales was where the wordless argument stopped. 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;&lt;strong&gt;Sound off by default (20 September).&lt;/strong&gt; 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;&lt;strong&gt;The idle line became a teacher only (19 September).&lt;/strong&gt; 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 60; &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-09T00: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 other 60. There are no ads, no subscription and nothing else to buy. Here is the whole model in one table, the paid-app plan it replaced, and how the purchase turned out to be too quiet for App Review.</summary>
    <content type="html">&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, no subscription and nothing else to buy.&lt;/p&gt;

&lt;p&gt;Here is the model in full, then why 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-299-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 forever. Not a trial, never gated&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Chapters II–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;—&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The price on the unlock screen comes 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. The app has no price written into it 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 &lt;strong&gt;Open Chapters II–IV&lt;/strong&gt; button under Chapter I on the chapter wall, which carries no price;&lt;/li&gt;
  &lt;li&gt;any unlit level of Chapters II–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: not at launch, not when you come back, not after a solve, and not 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 is also not a promoted purchase on the App Store page, which 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. VoiceOver says “not purchased” for the same reason, never “locked”. Your star total is not shown on the unlock screen either: 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 from 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, alongside 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 removes 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 puts it plainly: the free chapter, not the price tag, is now what does the persuading. The store description also 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-299-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 the launch plan considers still reads as something crafted rather than 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. Its judgement is that no price below $2.99 would earn back what it costs in credibility. It also means that, for the first year at least, 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 mean network code and a third-party SDK in 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: not when it is shown, not 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, not money. 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;buying-once-should-mean-owning-it&quot;&gt;Buying once should mean owning it&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Family Sharing is on.&lt;/strong&gt; One purchase covers your family group, and the game treats a shared purchase exactly like your own.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Restore purchases is always visible&lt;/strong&gt;, 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;/li&gt;
  &lt;li&gt;&lt;strong&gt;Once granted, the unlock stays.&lt;/strong&gt; 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. Locking a paying player out of an offline game to re-check a purchase is a failure the design rules out.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Chapters still open in order.&lt;/strong&gt; 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 isn’t a surprise. Within a chapter you can skip past up to three unsolved levels, so no single puzzle walls you off.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;No error codes.&lt;/strong&gt; 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;/li&gt;
&lt;/ul&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. It is one view used in both places, 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 it, so the prompt 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 and nothing else, 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 all 80 of its levels</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-09T00: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 80 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. Here is how to solve one, and how that proof works.</summary>
    <content type="html">&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 rather than 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, with its own arithmetic rather than 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 60. 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;. If a level seems to need a guess, it doesn’t: the cards are 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-07T00: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. Here are 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. These are the ten names worth learning 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 threatens nothing and commits to nothing&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 what to do in them rather than how many moves deep they go. 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-04T00: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. The rules that are different are few, but most of them reverse a chess habit, and those are the ones that cost games. This 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;—&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. 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. It is also 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. Perpetual chasing is not adjudicated, so the app 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-03T00: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. Some free puzzle games are paid for with your attention, some with your patience, some with a subscription. Here is how each model works, how to spot it on a product page before you install, and the complete list of what 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. The question worth asking before you install one is who pays, and with what. Here are the common models, what each asks of you, and where each shows up on an App Store page. After that, 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 with a timer, boosters for sale and ads for extra moves are a common bundle in level-based puzzle sagas. Paid-upfront games are 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;&lt;strong&gt;Next to the Get button.&lt;/strong&gt; “In-App Purchases” there means something is for sale.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The In-App Purchases list&lt;/strong&gt;, 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;&lt;strong&gt;App Privacy.&lt;/strong&gt; This is what the developer declares about data, in 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, no lives and no 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 four packs bought separately cost $7.96, so the Complete Collection is cheaper. 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;What is free: all 64 campaign levels, Freeplay, the daily board, Hint, the Coach, Game Center and the Classic theme, one of seventeen. A paid theme can be previewed 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 here are their exact rules.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Inside a level, Undo is free and unlimited.&lt;/strong&gt; It 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;/li&gt;
  &lt;li&gt;&lt;strong&gt;Tokens are spent only in Freeplay,&lt;/strong&gt; the endless board, where tiles spawn at random. By default the app asks before it spends one.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Free tokens arrive on their own.&lt;/strong&gt; One arrives 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;/li&gt;
  &lt;li&gt;&lt;strong&gt;Running out doesn’t interrupt anything.&lt;/strong&gt; Tapping Undo with no tokens opens a sheet with the three bundles and a “Not now” button. The game carries on either way.&lt;/li&gt;
&lt;/ul&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 in the most direct way. A lives system makes failure cost time: you lose, and you wait or pay. In Millrace a loss costs one tap on Undo. The comment above that button in the source puts it plainly: 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. A hard level with a lives meter attached rewards waiting, not 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, 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 ruled out by design and are now ruled out by construction. 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; 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. That is the whole trade. 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 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; every level can be finished free; hints are never rationed, and undos are free inside levels, with tokens 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-09T00: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. The ones that didn&apos;t work aren&apos;t in the app. Here 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, not the first one found.&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 is a win in a real game. 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 had limits. 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.&lt;/p&gt;

&lt;p&gt;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. 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 quietly break a problem that used to be sound. If that happens, a player should get a smaller corpus, not 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 rather than a content decision and stores none of it. Mate-in-1 and mate-in-3 problems are checked during launch; the deeper two shards are checked 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, not 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 “Review — due today”, or as “Seen before — no new problems left” once the unseen ones run out. 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 instead of insisting on 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-09-27T00: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. Here are 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;—&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-09T00: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. That sounds like a slogan until you check it by machine; then it becomes 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, not written by hand, and none ships unless all five hold:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;It is solvable&lt;/strong&gt; within its move budget.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Its shortest solution is known exactly.&lt;/strong&gt; A breadth-first search walks the level’s entire state graph; the first win it reaches is provably the minimum. That number, not my estimate, is what the game calls the best possible.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;No thoughtless strategy wins it.&lt;/strong&gt; 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;&lt;strong&gt;Random play almost never wins.&lt;/strong&gt; Its exact odds are computed, not sampled. Above 2%, the level is gone.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;It is not another level in disguise&lt;/strong&gt; — 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 — many roads, no dumb ones. 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;an-earlier-version-looked-like-puzzles&quot;&gt;An earlier version looked like puzzles&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;That was structural, not bad luck. 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 asked only whether a solution existed: a floor with no ceiling.&lt;/p&gt;

&lt;h2 id=&quot;a-goal-a-greedy-player-can-chase-is-not-a-puzzle&quot;&gt;A goal a greedy player can chase is not a puzzle&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. What beat the clearing goal were 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; and it must 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. That is why Millrace has exactly one kind of goal: a measurement, not a lack of imagination.&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 restores the tension a slide-and-merge board lives on: it fills while you merge.&lt;/p&gt;

&lt;p&gt;It does not restore chance. 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 — it depends on tiles nobody has drawn — and a solver can only average over futures. With a visible queue there is nothing to average; breadth-first search is the correct model, not an approximation. The gate knows exactly what you know, and nothing more.&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; the rigour lives 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 — picking it first meant most candidates buried their own inlet on move one. The target is one or two doublings above the biggest starting tile, then comes 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 at the gate’s heart: 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 — keep the inlet clear, keep it clear then score, don’t lose on this move, herd the biggest tile to a corner, chase the target onto the vault — again under all 24 orders. Each is deterministic, so one playthrough is a proof, not a sample. A level ships only if all 280 fail.&lt;/p&gt;

&lt;p&gt;The battery’s first version was circular, and it’s worth saying so: 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; it is the skill the levels teach. The gate certifies that the content has depth, not that 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, not simulated. 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; the median sits 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. Those nine identical boards are why.&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;None of this is a script I ran once. The sixteen checks live in the test target; 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, naming the property that broke. A search that runs out of budget fails too — unproven is unshippable. And the gate must 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 rather than generated, 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 all 80&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 stop being a feeling and become 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, which is the point.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;The chapter is the depth.&lt;/strong&gt; 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;&lt;strong&gt;The budget is tight.&lt;/strong&gt; The deepest level needs all 16 of its 16 moves.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The result card tells the truth.&lt;/strong&gt; “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;&lt;strong&gt;A loss can say when it happened.&lt;/strong&gt; After a failed run, the card can name the move where the position became unwinnable — only 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, it isn’t. 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-09-19T00: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. Here is the product page, field by field.&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 and do different jobs.&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;One gap, plainly: AppMeta 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-09-12T00: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. Here is what that research found, and what follows from it 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 are a risk of their own.&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 is not the same as a pager on the bedside 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;That is the on-call problem in a few lines. 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;The caffeine nap has a well-known study behind it. 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 isn’t the same experiment, but it 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, because the uncertainty is expected.&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-09-05T00: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. Here are the rules, eight sessions worked through, what a small plate really 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. That is the trade: 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-08-29T00: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. Here is the map, two lines written out move by move, and a way to pick your first opening.</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). Two more names you will meet early are attacking methods rather than 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–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 setup was built for. 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-08-22T00: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. Here they are side by side, 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. What it does is keep those dates and tell 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;One honest caveat, because the schedules above make it matter: 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;The schedule belongs to your vet. The dates on the certificates belong to you, and keeping them is what lets you 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-08-17T00: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 are the same idea counted from opposite ends, and the scale most people use has a specific origin worth knowing.</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. The rest is detail, and the detail is mostly about 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;—&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;—&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Two rows break the simple subtraction. 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 older than strength training apps by decades, but the generic ones ask how hard the effort &lt;em&gt;felt&lt;/em&gt;, which is a poor fit for a set of squats. 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, which is 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 rather than 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;Within about a rep, on average, 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 helps you feel at home under a bar, but it doesn’t automatically make 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. The practical reading is that RPE 7 is a fuzzy number and RPE 9 is 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, built around what the research above says goes wrong.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Rate the last rep, straight after the set. Not the set as a whole, and not after the rest period, when the memory has already softened.&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, the extra precision is imaginary.&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;One more: 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 instead 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 honest 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;What matters more is consistency. 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 to give once a fortnight is just a 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, but 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-09T00: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. Here 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;Here is every rule with the arithmetic worked all the way out. The part about why the fair rule is hard to propose comes after the numbers, because the numbers 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 convention rather than rule. 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. Announcing which one you used is what matters. 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;The headline is the last column. An even split charges Alex $20.62 more than the salad actually cost — on one dinner, at a table of only four. Twenty-six dinners a year with the same group and the same ordering habits and that is $536 moving from the salad to the ribeye — not as a grievance, just as arithmetic.&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 its quietest damage, 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 &lt;strong&gt;$14.40 swing on one bottle he never touched&lt;/strong&gt;. 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 conducting an audit over a wine bottle, and it is a price worth paying.&lt;/p&gt;

&lt;p&gt;So the two rules are not the same rule, and conflating them is where tables go wrong. 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, it is completely transparent, 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, invisibly.&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 is a function of the social situation, not the arithmetic. Here 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 quietly 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 rather than 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 not more accurate, only 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 does it. A spreadsheet does 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 not better math. It is to move the itemising off the table: do it privately, on one phone, in under a minute, and present a finished number to each person rather than a process. People do not object to receiving a total. They object to watching one get constructed about them.&lt;/p&gt;

&lt;p&gt;That is the whole shape of &lt;a href=&quot;/apps/rightsplit/&quot;&gt;RightSplit&lt;/a&gt;. 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 entire subject of this post — is Pro+, at $3.99 a year or $7.99 once. And the OCR is exactly as good as Apple’s OCR: 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 — 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; deserves an honest mention too: it 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 — not $6.00 each.&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, not to the head count.&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;The rules are all fine. Picking one before the bill arrives, instead of after, is the entire trick.&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-25T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">Between two competently written strength programs run by the same person for the same twelve weeks, the difference in results is small. The difference between twelve weeks completed and twelve weeks abandoned in week five is enormous. So the useful comparison is not which program is best — it is which one survives your actual calendar. Here is that comparison, 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. Almost none of it is decisive. 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;What decides the outcome is 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–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 rather than reduce.&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–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. The split silently becomes a lopsided three-day 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–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-it-up logic collapses inside 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–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–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 instead of changing 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–4&lt;/td&gt;
      &lt;td&gt;40–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 wanting a long runway 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 is not what separates these programs.&lt;/strong&gt; Full body and PPL sit at three and two, and once weekly volume is held equal the frequency research is not 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, not a law.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The failure modes, by contrast, are specific.&lt;/strong&gt; PPL does not fail because six days is too much volume; it fails because six fixed slots is too many places for a week to break. Novice linear progression fails because it is designed to end, and almost nobody has a plan for 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–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 simultaneously&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;, not to your 1RM&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;There is no failed session, only a lighter one. 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–6 week cadence&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;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, 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. That is not a step backwards. The bracket resets and you climb it again, and it 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;, and 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 the whole program. That last set is taken for as many quality reps as you have, and its rep count is your progress signal — the fixed sets are 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, run it again. 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; put muscle-strengthening activity at two or more days a week for adults, covering all major muscle groups. That is a health floor, not a strength target.&lt;/p&gt;

&lt;p&gt;For building strength, three to five days is where most sustainable programs live. But pick your number backwards, not forwards. 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 not a program, it 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 implementation — 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. What the rule cannot tell you is 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; Not for you, and not for the 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, and 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, divide by eight. That is your days per week — not your intention, not your best month. 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 and 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 becomes a skipped one. 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 rather than the heavy lifts.&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: percentage cycles or autoregulation, and expect progress measured 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 that lets you swap the movement without deleting a day — organised by movement pattern, not by a fixed list of named exercises.&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, get eyes on it from a clinician or a coach who can see 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. That assumption is doing more work than any of the programming.&lt;/p&gt;

&lt;p&gt;Linear progression is the only model on 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. This is the unglamorous reason logging apps exist, and why 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, a number you can add to any logged set rather than a field imposed on every one. The honest 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; is 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 rather than buried in an algorithm: 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 the reason your programs die is that &lt;em&gt;choosing&lt;/em&gt; one is the friction, &lt;a href=&quot;/alternatives/fitbod/&quot;&gt;Fitbod&lt;/a&gt; is genuinely the better tool. Its generated-session model removes the decision: you open it and it tells you what to do today, adjusted for yesterday. No amount of good template design in a manual logger replaces that. The trade is subscription-only pricing and proprietary reasoning.&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 one listed that can change your program when your week changes.&lt;/p&gt;

&lt;p&gt;For the category sorted by pricing model, there is 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 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;Days per week is a measurement, not a decision.&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, which is why the log, not the template, is what finishes the twelve weeks.&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-08-01T00: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. Here is everything a tool will ask you for, and where it 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 rather than 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. The difference matters more than 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 rather than later.&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-09T00: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 explain why your blocker cannot name the apps you blocked, why notifications still arrive, and why every honest answer to &apos;can this be bypassed&apos; is 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 works by asking iOS to do the blocking on its behalf, through three frameworks Apple shipped in 2021 and has extended in small increments since.&lt;/p&gt;

&lt;p&gt;That distinction is not pedantry. It decides what your blocker can do, what it will never do no matter how much you pay, and — the part nobody puts in the App Store screenshots — exactly how you get out.&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, collectively 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;The sequence in a real app 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 your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DeviceActivityMonitor&lt;/code&gt; extension get woken at interval boundaries and usage thresholds to change the store.&lt;/p&gt;

&lt;p&gt;Two practical gates are worth knowing before you assume the category is bigger than it is. 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” is really doing it at Apple’s chosen moments.&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;This is the single most consequential design decision in the whole API.&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 is Apple’s, not the developer’s. It renders out of process, it lists your installed apps, and what it returns is 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. It hands that blob back to ManagedSettings to raise a shield. It never receives a bundle identifier or a display name. There is no way to reverse it. A token is also only meaningful 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;The privacy consequence is real and worth saying plainly: a screen-time app physically cannot log that you blocked Grindr, or Robinhood, or your ex’s favourite app. Not “promises not to” — cannot. That is privacy by construction, and the strongest such guarantee in any category I have shipped into.&lt;/p&gt;

&lt;p&gt;The product consequence is a genuine 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, which makes support (“it isn’t blocking anything”) an exercise in guided screenshots.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That trade is Apple’s to make, not the developer’s. I think it is 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. The column that matters is not price, it is 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 — 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 — state is local and enforced by iOS&lt;/td&gt;
      &lt;td&gt;People who want a different unlock condition 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) rather than 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, 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 just 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 rather 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 honest notes on that table. A DNS filter is the only row that touches apps you did not enumerate, which is why it is 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. Then 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 is fixing the wrong half of the loop, and a Focus mode is the better tool — or both 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 is doing it with a different mechanism.&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 the reason is deliberate: if a third-party app could permanently restrict your phone, the first malicious app to ship would brick a lot of phones. Apple keeps the exit in your hands on purpose.&lt;/p&gt;

&lt;p&gt;So the useful question is not whether there is a way out — there always is. It is how long the way out takes, and whether the effort lands somewhere useful. Here is the actual 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–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–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–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, 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 deserve 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 — an app can watch its own authorisation status and know the moment you walked out. Whether it should do anything with that, beyond quietly 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” collapses. The only real variable 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; — that a cost you set yourself, inside the software, is a cost your craving can renegotiate from inside the moment of craving. The API reality above is the structural version of the same argument. Since revocation is always about fifteen seconds away, 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. Time-of-wait 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;That is not the same as saying the other designs are wrong. 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 — a breath, a pause, a question. If your problem is that your thumb arrives before your intention does, that is a better-shaped intervention than a hard gate, because the reflex is what it targets. A gate you have already earned 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 rather than software you authorised. The cost is that you have 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 free is a real advantage that a $19.99 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. It is not doing anything 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 — and 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 instead of Apple’s generic restriction screen. &lt;em&gt;3,412 steps until unlock&lt;/em&gt; is a destination. &lt;em&gt;This app has been restricted&lt;/em&gt; is a wall. 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; &lt;a href=&quot;/journal/how-many-steps-a-day-to-aim-for/&quot;&gt;what the step-count studies support&lt;/a&gt; covers it. $1.99/month, $9.99/year, or $19.99 once, each price checked in August 2026.&lt;/p&gt;

&lt;p&gt;The honest constraints are the same ones on this page. EarnLock cannot see which apps you blocked either. It does not stop notifications. It is iPhone and Apple Watch only, and there is 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 a tool with no exit is a tool people delete. And if you open Settings and revoke its authorisation, every shield drops and there is nothing it can do about that — which is true of every Family Controls app named on this page, and worth knowing before you pay any of us. (The data discipline behind that, and every other Lagerland app, 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;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 — and it also cannot pre-fill 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; The only real variable 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-07-25T00: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. Here are 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 runs 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. Below are the numbers for each step, then 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; puts it plainly: a message must fit the limits of both sender and recipient. The smallest limit on the route is the one that counts.&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;Compression has a floor, and the five-minute row of the table finds it: 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;The trade is simple: 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-07-20T00: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;). The rest of this page is detail around that sentence: 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;The trap in the downloadable report is that both money columns are per unit. 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;Treat that as arithmetic, not a quote. 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-25T00: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. It is not. Each language Wikipedia is an independent encyclopedia with its own editors, its own inclusion rules, and its own article set, and two editions can disagree about facts, framing, length, and whether a subject merits an article at all. Here is what actually differs, how big each edition really is, and why reading a topic twice 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, differently sourced, with several paragraphs on fishing rights and local place-name history that English never had, and missing the geology section you came for.&lt;/p&gt;

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

&lt;p&gt;Almost every question people have about Wikipedia and languages dissolves once that one 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, its own administrators, its own notability rules, its own sourcing norms, its own deletion process, and its own article set. Articles are written locally by people working in that language. They are not derived from an English master copy, because there is no master copy.&lt;/p&gt;

&lt;p&gt;Four consequences:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;The languages sidebar is a claim about concepts, not 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, but as a seed rather than a pipeline.&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 the moment a local editor works on it. Which is immediately.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Image policy genuinely 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 no image in another, permanently.&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. None of that is a defect awaiting repair. It is what independent project means.&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 rounded hard and approximate as of 2026. Article counts change every hour; the live table is Wikimedia’s &lt;a href=&quot;https://meta.wikimedia.org/wiki/List_of_Wikipedias&quot;&gt;List of Wikipedias&lt;/a&gt;, which is the source to check rather than this page.&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, 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 is ranking 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. What follows is the shape of each, not a claim about any specific article, because the specifics 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 is the one worth sitting with. 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 land in different places. Reading both is how you find that out.&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 a threshold, three things follow: 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 different in kind 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 generally. They are a reason to know which edition you are standing in. A small edition is not worse. It is thinner, and thinness is a property you should be able to see.&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 practical 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; A Japanese rail line, a Finnish municipal reform, 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 frequently the real prize: local newspapers, national archives, ministry publications, regional academic presses.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Treat disagreement as the finding.&lt;/strong&gt; Where two editions differ on a date, a name, or a cause, you have located 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;This 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 the reference. What follows 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 rather than a scroll.&lt;/p&gt;

&lt;p&gt;A feed has a specific structure: items ranked by predicted engagement, no bottom, and a design objective where you leaving counts as 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 inverts three of those properties, almost by accident of the form:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The terminal action leaves the deck.&lt;/strong&gt; The point of a card is to make you open the article. 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 that is chosen in a menu, not inferred from dwell time. Interest categories work the same way. A declared preference is worse at maximising engagement than a behavioural model, and better at the thing 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 rather than when the 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;None of this makes a deck automatically virtuous. A swipe deck ranked on dwell time with a streak counter bolted on would be a feed wearing a costume. The form does not save you; it just makes the honest version easy to build and the dishonest version visibly gratuitous.&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 it is worth being precise about what that excludes.&lt;/p&gt;

&lt;p&gt;It runs on iPhone and iPad, iOS 18.2 and later. It carries 32 Wikipedia language editions — 32 of roughly 340, a real limitation and not a rounding error. 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 instead, is in &lt;a href=&quot;/journal/how-to-find-interesting-wikipedia-articles/&quot;&gt;a guide to finding interesting Wikipedia articles&lt;/a&gt;. Ad-free, no account, and the articles you save are kept 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. That is the trade for having no ads and no engagement model to feed.&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 rather than machine-translated English category names. In the other 15, For You and Browse fall back to random articles from that edition instead of pointing English names at a category tree that does not use them. That is the principle from the top of this page implemented in one place: the German Wikipedia’s category structure is the German Wikipedia’s, and pointing English category names at it returns the wrong articles or none. 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;What it does not do. It does not translate — if an article does not exist in the edition you selected, WanderWiki cannot conjure 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;And two genuine competitor advantages, because pretending otherwise would be silly. If you want the encyclopedia itself offline — the whole thing, 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 rather than 32, &lt;a href=&quot;/alternatives/wikipedia-app/&quot;&gt;Wikipedia’s own official app&lt;/a&gt; is built for that and is free. WanderWiki sits in the narrow gap between them: a reading surface for the encyclopedia you are not currently 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, not translated.&lt;/strong&gt; Each is an independent project with its own editors, notability rules, sourcing norms, and image policy. There is no English master copy for others to render.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The languages sidebar links concepts, not text.&lt;/strong&gt; Those links live in Wikidata and assert only that two pages are about the same subject — 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; rather than 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 mine the references list — local sources are the usual payoff.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Small editions are thinner, not worse — but thinness is 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-09T00: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 the answer is instant. No.&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;The certificate does not belong to the dog. It is filed mentally under the pet and it is, on paper, a document about a household with an animal named in it. That mismatch between how the document feels and what it contains is the whole subject of this post.&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 remarkably 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 microchip code is not a pet-only number. 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, not your details, but it is a useful reminder that the number is an index into a database about you, not 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;The user-facing feature is identical. You point the camera at a page, a moment passes, the fields fill in. Underneath, there are two completely different architectures, and they differ on 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;Read that last cost row carefully, because it explains the rest of the table. Server-side extraction has a marginal cost per page. That cost has to be recovered — through a subscription, through a clinic partnership, or through 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;The two rows where cloud wins are real, and anyone selling on-device processing should say so out loud. 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. And it 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, 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 rather than hard-code a marketing number.&lt;/p&gt;

&lt;p&gt;Here is the part that trips people up. Neither framework tells you anything about privacy on its own. An app can present the VisionKit sheet, get a beautiful deskewed image back, and then POST it straight to a server. The capture UI is not evidence. 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;Four tests. None of them requires you to read code, and they work on any health app, not just pet apps.&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 is behavioural rather than declarative. A marketing page can say “privacy-first” for free. A scan that completes with the radios off cannot be faked.&lt;/p&gt;

&lt;p&gt;The other three are declarations, worth reading rather than skimming. 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 — 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. You should not take my word for that. You should read the page and 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 quietly extend 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;Nothing on your side of the trade can change. 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 not to trust harder. It 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;This is where I have to be straight about the trade-offs in our own app, because 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. And the free tier limits how many documents you can scan, which is a business constraint, 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;What we are not willing to do is quietly route the page through a server and describe it as 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; Point camera, fields fill in. The difference is entirely in 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 genuinely wins on hard scans.&lt;/strong&gt; Bigger models, better on faded and creased pages, and they improve without an app update. That advantage is real and worth naming.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The asymmetry is the argument.&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 that 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-07-05T00: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;Because 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. If your roster has a name, write out the next 28 days as D, E, N and off. That list 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;Two things decide how hard a switch is: which way the clock moves, and 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 arithmetic is unforgiving. 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 rather than 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;Eleven hours isn’t an arbitrary line. 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;Twelve-hour shifts get a footnote. 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 looks at each window between the end of one shift and 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;None of this changes your roster. What it gives you is your own record of which changeovers cost 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-09T00: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 is the one method almost guaranteed to miss the expensive ones. Recurring charges do not live in one list. They live in eight, and the yearly ones are invisible eleven months out of twelve. Here 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. It 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 are the ones that renew far away from the decision that created them, and those are exactly the charges a short statement scan is structurally unable to show you.&lt;/p&gt;

&lt;p&gt;The better mental model: 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 of them already has a screen showing you its own slice. The audit is a route through those screens, in a sensible order, finishing with the statement rather than starting there.&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;A few notes on the paths, because they move.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Apple.&lt;/strong&gt; The highest-yield single stop for most iPhone users, and the one people skip 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; This is the step almost everyone skips, and it is where the strangest charges live, 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; Two separate lists, and the second one is the sneaky one. &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 quietly receiving since.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Email and purchase history.&lt;/strong&gt; Search your inbox for the renewal language rather than for 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. The reason is the next section.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Password manager.&lt;/strong&gt; Not a billing record, so do it last, but 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;Not all charges are equally findable. These are the categories that survive a casual audit, ranked roughly by how often I have watched 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 — this is exactly what it is for&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;Typically 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 the honest limit of any app-based audit. A direct debit set up by post is not in Apple’s records, not in PayPal’s, not in your inbox, and on the statement it looks like an ordinary bank transfer rather than 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. That is the whole mechanism, and it is worth making numeric, because the intuition runs the other way — 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. Nothing subtle is happening — we audit in three-month windows out of habit, and three months is the wrong instrument for a twelve-month event.&lt;/p&gt;

&lt;p&gt;Now put cost next to it. A $99-per-year subscription and a $8.25-per-month subscription cost you the same amount over a year. One of them you encounter twelve times. The other you encounter once, in a month you were not looking, in an amount large enough that you will assume it was something else. The yearly plan is usually the better deal and it is reliably the harder one to keep track of — which is also why the cheerful annual discount is offered so enthusiastically.&lt;/p&gt;

&lt;p&gt;Two consequences. Scan 13 months rather than 12, so a renewal sitting on the boundary cannot fall through the seam. And when you find an annual charge, write the renewal date down on the spot — you will not meet 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 I would rather name them than pretend they do not exist.&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 — a payment processor’s name, a parent company, an eight-character string. That is a real capability and no amount of manual discipline reproduces it.&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. These are the errors a list built from memory reproduces faithfully, because memory is where the error 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 it does them well. If your actual problem is &lt;em&gt;I do not know what I am paying for&lt;/em&gt;, an aggregator-connected tool is the right instrument and I will say so. The trade 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, not just the recurring ones, 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 is the answer to &lt;em&gt;how do I get the discovery without the access&lt;/em&gt;. It is slower. It is one afternoon rather than one tap. It also terminates — once you have the list, you have it, and the maintenance 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;This is where most audits fail. 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 do that. A spreadsheet does, until the third week. &lt;a href=&quot;/apps/allpaid/&quot;&gt;AllPaid&lt;/a&gt; is the studio’s answer to this specific 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 gentle 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;The honest limitation is the whole 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 the list. Those are two different jobs and I would rather be clear about which one the app does.&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, Subby is freemium with its own premium unlock — and 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, at the cost of being a web account rather than 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 rather than leave a gap.&lt;/p&gt;

&lt;p&gt;One habit beats all of it: the moment you start a free trial, write down the date it converts. That is the one category on the hiding list you can eliminate at signup instead of hunting for a year later.&lt;/p&gt;

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

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;There is no one list.&lt;/strong&gt; 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;&lt;strong&gt;Start with Apple, not the bank statement.&lt;/strong&gt; 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;&lt;strong&gt;Scan 13 months of statements, not three.&lt;/strong&gt; 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;&lt;strong&gt;PayPal and Subscribe and Save are the two most-skipped steps.&lt;/strong&gt; Years of small-merchant billing agreements live in the first; recurring household shipments live in the second.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;A bank-linked app genuinely wins on three things:&lt;/strong&gt; charges you never knew existed, price rises, and duplicates. The price is aggregator read access to every transaction, forever, not only the recurring ones.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Finding the charges and keeping them are different jobs.&lt;/strong&gt; The checklist finds them; 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-25T00: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;—&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-06-23T00: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 — a YaneuraOu pawn is 90 points, not 100 — and the conclusion is still wrong, because the same nominal material edge buys far less in a game where captured pieces come back as drops. Here is 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;. They divide by a hundred out of chess habit 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. The position is probably fine too. And 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;This is the conversion table nobody hands you. Reference first; 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;&lt;strong&gt;The sign is from the side to move.&lt;/strong&gt; 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, not a normalised display.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The scale is the engine’s, not the game’s.&lt;/strong&gt; &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. Note how close that is to a chess centipawn: 90 units per pawn against 100. The reason shogi evals &lt;em&gt;look&lt;/em&gt; like four-digit numbers and chess evals like small decimals is display convention — chess front-ends divide by a hundred before drawing anything, shogi front-ends print the integer. Tunings shift these constants, so if you need them exact, read them in the source rather than 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 out of win-rate fitting in the elmo and YaneuraOu learning code — 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, not 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, not the win.&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;Not a magnitude. A proof.&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, 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 is not removed from the game. It goes to your hand — the &lt;em&gt;mochigoma&lt;/em&gt; (持ち駒), which 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;So a capture is not a subtraction. It 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 carry the most useful piece of shogi arithmetic: &lt;strong&gt;promoted pieces revert when captured.&lt;/strong&gt; 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;Now put the numbers together. 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. That is not the engine being dramatic. That is the game.&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 calm down because material leaves and positions simplify toward technically drawn endings. Shogi has no such drain. Trades load both komadai and sharpen the position rather than quieting it. 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 even where the table cannot.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A piece in hand has no travel time.&lt;/strong&gt; A knight on your second rank needs several moves to matter. A knight in hand is already everywhere: it arrives on any legal square in one move.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It has not committed to anything.&lt;/strong&gt; A silver on the board is an argument about one part of the board. A silver in hand is a live threat against every weak square at once, and your opponent has to answer all of them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It is not blocking your own pieces&lt;/strong&gt;, which is no small thing 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 — 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 transformation even though the material table does not.&lt;/p&gt;

&lt;p&gt;The 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; is not “very good”, it is “there is a forced mate, and here is the proof, seven moves long”. Three consequences follow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It is not on the eval scale.&lt;/strong&gt; 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, not an evaluation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A negative mate score is the one to read.&lt;/strong&gt; &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;&lt;strong&gt;An engine mate is not a tsume.&lt;/strong&gt; &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. There is also no score at all 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 makes that argument stronger in two specific 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 buys less and costs more. Comparing a shogi “depth 20” with a chess “depth 20” is meaningless: 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 &lt;strong&gt;longer drop sequences&lt;/strong&gt;: five-move nets starting with a pawn dropped on an empty file to be promoted three moves later. Those are exactly the moves a club player had no chance of finding at the board and no chance of generalising afterwards. The mistakes that actually decided your game — the hanging silver, the knight drop that would have forked king and rook, the reflexive promotion, the edge pawn that opened your mino castle — are visible far shallower.&lt;/p&gt;

&lt;p&gt;So no ply number here, the way the chess post gives one 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;Say the true thing first. &lt;a href=&quot;/alternatives/lishogi/&quot;&gt;Lishogi&lt;/a&gt; is free, open source, and genuinely 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 — being open source — lets you read exactly what the analysis did rather than trust 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, that is the answer and it is free. &lt;a href=&quot;/alternatives/piyoshogi/&quot;&gt;PiyoShogi&lt;/a&gt; is likewise a fine 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;an-evaluation-is-a-verdict-without-a-reason&quot;&gt;An evaluation is a verdict without a reason&lt;/h2&gt;

&lt;p&gt;Everything above teaches you to read a number that, once read, still does not tell you what to do. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-980&lt;/code&gt; is a verdict. It says 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;Translating verdict into 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 do not exist in that taxonomy: 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 those from scratch rather than adapting a chess list — 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, no account, and no 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 Premium is the tier that raises engine depth and shows multiple candidate lines.&lt;/p&gt;

&lt;p&gt;The limitation is the exact flip side of that design. Shogiful leads with the sentence rather than the number, and it has no online human play at all — so if what you wanted was the eval graph itself, deep and shareable, lishogi does it better and 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 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;&lt;strong&gt;A shogi eval is not a centipawn — but the units are close enough to fool you.&lt;/strong&gt; YaneuraOu anchors to a table where a pawn is about 90 against a centipawn’s 100; shogi front-ends just print the integer instead of 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;&lt;strong&gt;The bands, for a club player:&lt;/strong&gt; 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, not physics, and they move with the engine.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Every capture counts twice&lt;/strong&gt;, because the piece goes to your hand rather than off the board. 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;&lt;strong&gt;A piece in hand beats the same piece on the board&lt;/strong&gt; in most positions: no travel time, no positional commitment, and a live threat against every weak square at once. This is most extreme for the lance and knight, which cannot turn around.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;A mate score is categorical, not numeric.&lt;/strong&gt; 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;&lt;strong&gt;More depth is not more instructive.&lt;/strong&gt; 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-06-20T00: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 is a slogan, not a finding. The large studies of step counts and health point lower, and they agree with each other more than the headlines suggest. Here is what they measured, what they 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. Ten thousand is not where the studies point; it is where a slogan pointed. The four studies below are the ones most of the numbers you read come from.&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–8,000 a day in adults 60 and over, and 8,000–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–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. Read the numbers as where the curve bends, not as a dose that guarantees 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;Not 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–7,499&lt;/td&gt;
      &lt;td&gt;Low active&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;7,500–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 the number to get right first is the daily total.&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. A daily total counts every step: the kitchen, the office, 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. That number, not 10,000, is your starting point.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Set the goal one walk above it.&lt;/strong&gt; A goal you reach on an ordinary day without trying is no goal. A goal you only reach on your best days is a lockout. 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 is cheap. Starting too high and quitting is not.&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 instead of one compromise number.&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 choice of goal decides whether it feels like a 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 instead of showing a stale 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;A daily threshold isn’t the only design. Some step apps sell screen time by the step instead; &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 a starting point for a much lower baseline, not a destination.&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-09T00: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. Here is what belongs in it, and who actually asks for what.</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 almost useless. 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 second wrong model 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 at exactly the moment it is needed, because emergencies do not happen at home.&lt;/p&gt;

&lt;p&gt;So before the argument, here is 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 — 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. This is the single most valuable line in an emergency&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 get left out of almost every home record, and they are the three that cost you most when missing. The &lt;strong&gt;adverse-reaction line&lt;/strong&gt;, because nobody writes down the thing that went wrong two years ago. The &lt;strong&gt;registry&lt;/strong&gt; 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 precisely to answer that question, and it will not help if your contact details in that registry are three addresses out of date. And the &lt;strong&gt;after-hours hospital&lt;/strong&gt;, which you 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-actually-need&quot;&gt;Which documents does each situation actually 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 actually 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;—&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 window is set by the carrier, 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;The international row is the one to take seriously. Nobody should take pet-travel rules from a blog post, including this one. The requirements are country-pair specific, they change, and the failure mode is your animal being 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-categories-not-a-schedule&quot;&gt;Core vs non-core vaccines: categories, not a schedule&lt;/h2&gt;

&lt;p&gt;This is a taxonomy, not a dosing plan. 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 rather than 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;Note that “core” is not a permanent list. 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 is regional rather than global. That single change is the argument for checking a live guideline rather than trusting anything, including this table, that was written on a fixed date.&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;Two reasons, and only one of them is obvious.&lt;/p&gt;

&lt;p&gt;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 not a record.&lt;/p&gt;

&lt;p&gt;The second is structure, and it is the one that quietly 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, and a source document is not an answer. What a vet wants is 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 are the same failure wearing modern clothes. The information is technically present and practically unreachable, 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-actually-require&quot;&gt;What does a 20-second record actually require?&lt;/h2&gt;

&lt;p&gt;The real test is narrow. 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;&lt;strong&gt;It has to work with no signal and no login.&lt;/strong&gt; Veterinary waiting rooms are frequently concrete boxes with terrible reception, and the moment that ruins the twenty seconds is a login screen followed by a password reset email you cannot receive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It has to produce one artifact, not fourteen.&lt;/strong&gt; A single PDF with vaccinations, medications, weight, and history is a thing you can hand over, email ahead, or print. A camera roll is not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It has to be answerable, not just searchable.&lt;/strong&gt; “Next due” beats “here is the certificate.”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It has to keep the original.&lt;/strong&gt; 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 exactly this shape. 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 rather than a number, holds the microchip number, with the insurance policy and pet-passport documents attached alongside the clinical history 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;The constraints are real. 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;And here is the honest part, because it matters more than the pitch. &lt;a href=&quot;/alternatives/petdesk/&quot;&gt;PetDesk&lt;/a&gt; does something Pawza structurally cannot. It connects to participating veterinary clinics, so it can carry appointment booking and the reminders your clinic itself sends. Pawza cannot do that, and will never be able to, 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 divides along similar honest 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 is twelve categories&lt;/strong&gt;, not one folder: 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, not a schedule.&lt;/strong&gt; WSAVA, AAHA and AAFP set the categories; your vet and local rabies law set the intervals — and the categories 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, not a summary you made yourself. 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;

&lt;p&gt;The paper is fine. The problem is that the paper is at home, and your dog is here.&lt;/p&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-09T00: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, not the rules, is what stops most chess players at the door. Here 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 quietly close it. Not because the rules were hard. They never reached the rules.&lt;/p&gt;

&lt;p&gt;The kanji on the pieces, not the rules, is the wall. So before any of the design story, here is the thing you actually came for: 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 is fourteen distinct things to tell apart by character alone. Chess gives every piece its own shape, which is exactly why “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, four things will trip you up — and they are the same four every time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The gold is the centre of gravity.&lt;/strong&gt; The gold general moves one step in any orthogonal direction plus the two forward diagonals: six squares, 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 is the tricky one.&lt;/strong&gt; One square straight forward, or one square in any diagonal — five squares. 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 precisely 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, forever. Both are commitments. Once advanced, they do 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 the diagonal capture you have wired into your hands from chess. There is no two-square first move and no en passant. There is, instead, the drop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Drops are the rule that changes everything.&lt;/strong&gt; When you capture a piece it joins &lt;em&gt;your&lt;/em&gt; hand and can later be placed — dropped — onto any empty square as your whole move, fighting 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–9 right-to-left&lt;/strong&gt; from Black’s side; 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–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–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;So 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; — and 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-real-barrier--and-why-i-didnt-just-translate-them&quot;&gt;Why the characters are the real barrier — and why I didn’t just translate them&lt;/h2&gt;

&lt;p&gt;Everything above is the 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;The obvious question is why shogi can’t simply draw a knight as a horse the way chess does. The answer is that the piece design is load-bearing. All forty pieces are one shape and one colour; ownership is shown by which way the wedge points, because that has to survive the drop rule — a captured piece joins your hand and comes back fighting for you. Fixed colours would lie about ownership; the rotating wedge 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 is a state change, not a piece swap. It is a beautifully compact system &lt;em&gt;if you read the characters&lt;/em&gt;, and an undifferentiated field of identical wedges if you don’t.&lt;/p&gt;

&lt;p&gt;A board you can actually read needs three things, not one:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Identity&lt;/strong&gt; — a distinct, instantly-parseable symbol per piece. This is the easy part, and where most sets stop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Movement&lt;/strong&gt; — the part that matters. A newcomer doesn’t know a lance only goes forward, that a knight has exactly two destination squares, 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 — which pays off most with that gold family, where promoted silver, knight, lance, and pawn all move alike and the icons make the family resemblance visible instead of four arbitrary facts to memorise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Promotion state&lt;/strong&gt; — traditional sets flip to red characters; a Western set needs an equally unmissable change, not just a tint, because “did that silver promote?” is exactly the question you can’t afford to get wrong when you’re working out whether it can retreat.&lt;/p&gt;

&lt;p&gt;There’s one decision hiding in plain sight: 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 is asking for an informed decision before they’ve seen the board. The locale already answered the question; the toggle in Settings is 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;Here’s the honest trade-off, because it’s real: the broader shogi world runs on kanji. Books, problem collections, Japanese apps, real boards, every diagram on every shogi site — all 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 built to be temporary. The piece guide is one tap from every game, showing both styles side by side; training introduces the characters progressively — you meet 銀 &lt;em&gt;after&lt;/em&gt; you already know how a silver behaves, which is dramatically easier than learning symbol and behaviour at once. Behaviour first, symbol second, is the entire thesis. Nobody learns chess by memorising the letters K, Q, R, B, N before their first game; shogi outside Japan has effectively demanded the equivalent for decades, 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. What’s 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. The piece set isn’t a feature; it’s the precondition for every other feature.&lt;/p&gt;

&lt;p&gt;If what you want is ranked play against humans, the online platforms are the right tools — and worth knowing the board there is all kanji, which is the whole 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 — there’s &lt;a href=&quot;/guides/best-shogi-apps-iphone/&quot;&gt;our honest 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 — 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, an honest 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-25T00: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. Here 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;Here 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;Three things stand out.&lt;/p&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;Honestly, the 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-05-30T00: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 rather than one big one, and most of the confusion comes from not knowing which one applies. Here is the situation-by-situation table, the arithmetic for the awkward cases (pre-tax or post-tax, the bar tab, the bill that already includes a gratuity), and where every number comes from.</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. Here they are, followed by 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–20% of the bill before tax&lt;/td&gt;
      &lt;td&gt;$60 of food: $9–$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–15% of the bill; $2–5 for pizza, by size and difficulty&lt;/td&gt;
      &lt;td&gt;$32 order: $3.20–$4.80&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Bartender&lt;/td&gt;
      &lt;td&gt;$1–2 per drink, or 15–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–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–$10.60&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Hair stylist&lt;/td&gt;
      &lt;td&gt;15–20%, shared among everyone who worked on you&lt;/td&gt;
      &lt;td&gt;$70 cut: $10.50–$14&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Hotel housekeeping&lt;/td&gt;
      &lt;td&gt;$2–5 per day, left daily&lt;/td&gt;
      &lt;td&gt;4 nights: $8–$20&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Valet&lt;/td&gt;
      &lt;td&gt;$2–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, 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 15% is where guidance and habit overlap, and 20% is the top of the range rather than the norm.&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. Picking one and using it every time is the useful habit.&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 is expensive. A party of eight, $420 of food, 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. Leaving something extra for exceptional service is still your choice; doing it by accident is the thing to avoid.&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–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–$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–$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–$2 is 15–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;What it won’t do is choose the percentage. RightSplit doesn’t know whether you are at a buffet or a steakhouse, so the table above is still the part you bring.&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–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–15%, taxis and haircuts 15–20%, housekeeping $2–5 a day, valets $2–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–2 a drink and 15–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-09T00: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 instead.</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 so far as to ship you a physical NFC tag — lets you unlock with the tag from across the room.&lt;/p&gt;

&lt;p&gt;These are not blockers. They are friction. The distinction matters.&lt;/p&gt;

&lt;p&gt;A blocker has a cost you cannot pay from inside the moment of 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;The reason every app in this category eventually adds a tap-through escape is App Store ratings. The user sets up the blocker on a Sunday afternoon when they are calm, and they encounter the blocker 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 rules the rating distribution ships in the next release.&lt;/p&gt;

&lt;p&gt;So the apps end up with a door, and the door gets easier to open 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. They set the timer. They picked the pause length. None of these are obstacles in the moment of craving — they are bookmarks from a previous 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 — that’s the wait-out model. one sec and ScreenZen do this. It does not work, because waiting is itself a tap. The user sets down the phone, picks it back up, ten seconds passed, the lock is gone. The user paid in attention, which is the same currency they were trying to defend in the first place. Nothing about the wait translates into anything the user benefits from later.&lt;/p&gt;

&lt;p&gt;The body is the other candidate. If the unlock costs steps, or active minutes, or active calories, the user cannot pay it from the couch. They have to go outside, or get on the floor, or move through the room. And — this is the part that makes the design defensible rather than merely strict — the cost is denominated in something the user’s life &lt;em&gt;also benefits from&lt;/em&gt;. 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 on Apple Health. Steps in the free tier. Active minutes or active energy in Premium. The user picks the goal on a calm day. The Thursday version of the user does not get to renegotiate it, because the Thursday version of the user does not have a 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;There is a second design choice that follows from the first.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/journal/what-an-iphone-app-can-actually-block/&quot;&gt;Apple’s Family Controls API&lt;/a&gt; will, by default, render 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 teaches the user nothing — no count of what is left, no relationship to the goal, no sense that the cost is reachable.&lt;/p&gt;

&lt;p&gt;EarnLock paints its own shield. The shield shows 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;. When the user attempts to open Instagram, they are not told they are restricted. They are told they are 2,026 steps from Instagram. The unlock is a destination, not a wall.&lt;/p&gt;

&lt;p&gt;This is small but it matters. A wall produces resentment. A destination produces motion. 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 does ship two real costs.&lt;/p&gt;

&lt;p&gt;The first is that some days the user will not hit the goal. They will not see Instagram that day. The right product response is to make that survivable without being undermineable. 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. It is the door for the genuine emergency, and only that.&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 the user quits the whole thing. EarnLock ships a streak because users ask for it, but a single rest day per week protects the count, and there is no notification shaming the user for missing a day. The streak is allowed to exist; it is not allowed to 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 is: any time you ship a streak, you owe the user a rest mechanism, or you are building a guilt loop with a different label.)&lt;/p&gt;

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

&lt;p&gt;There is one more piece worth naming, because it is the part most blockers get wrong on day one.&lt;/p&gt;

&lt;p&gt;When a user installs a screen-time app, the app does not know anything about that user yet. It does not know which apps they actually overuse, what time of day the urge spikes, or how much real time they would have spent had nothing blocked them. So the app picks a default — usually generous, sometimes hostile — and the user either bounces because it is too strict or bounces 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, for how long. At the end of the week it shows the user a screen that says, in effect, &lt;em&gt;here is what you would have lost — about 30 minutes a day, 23 separate block events this week — based on your own behaviour. Enable real blocking?&lt;/em&gt; The user makes the call with their own data, not with a guess from a stranger who has never seen their phone.&lt;/p&gt;

&lt;p&gt;This is, I think, the right default for any tool that proposes to change a user’s behaviour. The first week should not be the tool acting on the user. It should be the tool earning the right to act, by demonstrating that it understands what is actually happening.&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 structural rather than behavioural.&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. This is, by a wide margin, the most psychologically intimate dataset a phone can produce — more intimate than location, more intimate than messages, more intimate than the photo library.&lt;/p&gt;

&lt;p&gt;The only safe thing to do with that data is to never let it leave 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 — 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;This is the right default for any app that sits between a user and their own behaviour. There should not be a database that knows the user tried to open Instagram 47 times last Tuesday. There should not be a server that knows they missed their step goal for a week in February. There should not be an account that ties any of this to an email address. The mechanism is private because the mechanism is &lt;em&gt;intimate&lt;/em&gt;, and the right response to intimacy 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 honest 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.) A screen-time app with no analytics SDK cannot run growth experiments on cohorts of strangers. A screen-time app with no tap-through escape will get some one-star reviews from people who wanted a door.&lt;/p&gt;

&lt;p&gt;These are the costs. I think they 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 not a blocker — it is decoration. A screen-time blocker that ships behavioural data to a third-party server is not a tool — it 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; is the version of the category that 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-05-16T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">The keyword field is the one piece of App Store metadata that customers never see, and it decides a lot about who finds you. Apple&apos;s rules for it fit on an index card. Most of the advice around it is folklore. Here is what Apple actually documents, what it doesn&apos;t, 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.” Here are its rules in one place, with where each one comes from.&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. That is why the no-spaces rule matters. A field written the way people write lists, with a space after every comma, loses one character at every comma. Ten terms, nine wasted characters.&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;This is where most of the wasted characters come from. Apple documents more of it 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;Fourteen words, none of them in the name, subtitle or category, no spaces after commas, one form of each word. It only works if the app really does track mood, water and sleep. 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 actually 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. That is the strongest argument for treating the field as a small, planned change each release rather than something you rewrite in a hurry. 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-08-14T00: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, they get rendered there, and you download the result. This is a strange architecture for a product whose entire input is content under NDA. Here&apos;s why Mac-native makes more sense — and the structural reasons almost nobody builds it that way.</summary>
    <content type="html">&lt;p&gt;The App Store screenshot tooling category is, on reflection, a slightly absurd one.&lt;/p&gt;

&lt;p&gt;Open the top three results on Google for “App Store screenshot generator” and try the workflow: you drop your pre-release screenshots — by definition material that’s still under embargo — into someone else’s web browser. The browser uploads them to someone else’s servers. The rendering, the device-framing, the AI translation pass all happen on infrastructure the vendor owns. Then you download the finished files and upload them, manually, to App Store Connect.&lt;/p&gt;

&lt;p&gt;This is a perfectly normal workflow. It’s also a slightly strange architecture for a tool whose entire input is content that hasn’t been announced yet. And once you notice that strangeness, you start to wonder why almost nobody builds the obvious alternative — a native Mac app that does the same thing, but where every byte stays on your machine until you push it to Apple.&lt;/p&gt;

&lt;p&gt;This post is an attempt to explain both halves of that question. Why Mac-native is the better architecture in this category. And why, despite that, almost nobody builds it.&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;When this post says “Mac-native”, it means a few specific things, all of which fall out of running the workflow in a real macOS app rather than 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. No upload, no remote render farm, no waiting for 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, your project files — all of it sits in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/Documents&lt;/code&gt; or wherever you put it. The screenshot tool reads and writes locally; 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, 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. They don’t sit in a SaaS vendor’s database.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is what “native” buys you. It’s not nostalgia for desktop software — it’s a specific architectural property: &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, in roughly ascending order of how often they actually matter:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NDA exposure.&lt;/strong&gt; 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 to have. Vendor policies that say “we delete uploads after rendering” are policies — they sit on the wrong side of your trust boundary. Native rendering eliminates the question.&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. For a workflow where you’re submitting to App Store Connect and may need to re-render the same project six months later for a minor update, determinism actually 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-10 seconds per screenshot once you account for upload, queueing, render, download. For a project producing 234 screenshots (6 device sizes × 39 locales), this is the difference between a 5-second render and a 5-minute render. 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; Once the rendering happens locally, the natural pricing model is a one-time purchase. The cost structure of a Mac app — distributed via the App Store, no server bills — supports a $20–$50 one-time price comfortably. The cost structure of a SaaS web app — render farms running 24/7 — pretty much requires a subscription. This is why Mockly is $12.99 once and most competitors are $19–$49 per month.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No account or login required.&lt;/strong&gt; This isn’t an ideological preference — there’s just nothing for an account to authenticate against. The app doesn’t store anything server-side because there’s no server. You don’t need to recover your account if you change machines, because there isn’t one. The friction reduction is real and the privacy reduction is real and they’re both downstream of “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 architecture is downstream of the business model, not upstream of it.&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 a per-user cost structure that scales sub-linearly with revenue. The web architecture provides all three: the render farm is the recurring cost, the locked-in cloud project files are the switching cost, and the marginal cost of one more user is ~$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 (it’s actually negative lock-in — 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;In other words: the Mac-native architecture is structurally better for the user and structurally worse for the vendor. Which is roughly the standard pattern for indie software, and the reason the category is dominated by SaaS even when SaaS isn’t the right product shape.&lt;/p&gt;

&lt;p&gt;This isn’t a moral critique of the SaaS competitors. AppLaunchpad, Screenshots.pro, Screenshot Studio, and the others are all reasonable products built within a reasonable business constraint. They’re just optimising for a different objective function, and that objective function happens to push 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. The architectural specifics:&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, deterministic. Project re-renders tomorrow produce bit-for-bit identical output. Every device class from iPhone 6.9” (1290×2868) down to Apple Watch (410×502) and up to visionOS (3840×2160) is handled by the same renderer.&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. There’s no Lagerland server 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. Credentials live in Keychain. The upload is a direct device-and-locale-aware submission to App Store Connect’s API — no manual browser uploads, no third-party intermediary.&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 cost structure supports this; the architecture supports the cost structure.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The price is the consequence of the architecture, not a marketing decision.&lt;/p&gt;

&lt;h2 id=&quot;a-note-on-fastlane&quot;&gt;A note on Fastlane&lt;/h2&gt;

&lt;p&gt;The honest answer to “why use a GUI tool at all” for many indie developers is: because the Fastlane setup cost is real. 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. But the setup curve is steep — &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. It’s a multi-day investment for first-time setup.&lt;/p&gt;

&lt;p&gt;For solo developers and small teams, the ratio of GUI-tool setup time (an hour) to Fastlane setup time (a few days) usually points to the GUI tool, especially if you’re shipping new screenshots a few times a year. Mockly is a GUI alternative for that audience; 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 — drop screenshots into a browser, render on the vendor’s server, 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: a third party sits 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, App Store Connect auth lives in Keychain. Every byte stays local until you push to Apple.&lt;/li&gt;
  &lt;li&gt;The reason web apps dominate isn’t user preference — it’s that the SaaS subscription business model only works if rendering happens on the vendor’s infrastructure.&lt;/li&gt;
  &lt;li&gt;Mac-native is structurally better for the user, structurally worse for the vendor. That’s 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, no subscription, no server, 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-08-14T00: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&apos;s actually good at. Here&apos;s 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 full of two-plus years of data they have never opened, never queried, and never learned anything useful from.&lt;/p&gt;

&lt;p&gt;That’s not their fault. The Health app is a beautiful container with very little interpretation. It shows you yesterday’s resting heart rate. It does not tell you which of your habits is consistently moving that number.&lt;/p&gt;

&lt;p&gt;Observa was built to be the interpretation layer. But before getting into how it works, here’s the more important practical question — the one I get asked most often.&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;The short answer: it depends entirely on what question you’re asking. The slightly longer answer breaks down 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, enough morning HRV readings, and enough workouts to start seeing single-variable correlations — &lt;em&gt;did this one habit consistently move this one metric?&lt;/em&gt; The kind of insights this surfaces:&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 of these is a single cause, a single effect, with enough same-condition observations (n ≥ 10) and enough opposite-condition observations to make a statistical comparison meaningful. The threshold I use in Observa is p ≤ 0.10 — looser than academic research, but appropriate for 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: anything multi-variable, anything seasonal, anything that depends on training cycles. The data is real; the slice is just 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;At around the 60-day mark, two things become possible. First, your personal baseline (the rolling mean and standard deviation for each metric — HRV (SDNN), RHR, sleep efficiency, deep-sleep share, REM share) stabilises enough that deviations become meaningful. Second, you have enough non-overlapping weekly samples to run multi-variable analysis.&lt;/p&gt;

&lt;p&gt;Multi-variable means: not “did caffeine affect my HRV?” but “did caffeine &lt;em&gt;combined with screen time on the same evening&lt;/em&gt; affect my HRV more than either alone?” That kind of compound pattern is where most of the actually useful self-knowledge lives. A late workout alone may cost you 4% deep sleep. A late workout &lt;em&gt;plus&lt;/em&gt; a caffeinated afternoon may cost you 19%. The compound is the answer.&lt;/p&gt;

&lt;p&gt;Sixty days is also, not coincidentally, around two menstrual cycles, two training mesocycles, and enough weekly variation to capture how your body changes through normal life rhythm. This is the window Observa uses for its Pro tier multi-variable engine.&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;Here is where things like &lt;em&gt;baseline drift&lt;/em&gt; become visible. Your resting heart rate is not a constant — it drops as you build aerobic fitness, drifts up during periods of stress, falls during taper weeks, climbs through respiratory infections you don’t always notice. Tracking RHR week-over-week against last quarter teaches you what “normal” actually looks like for your body. The same goes for HRV: seasonal swings of 10–20% are common, and reading a winter dip as “I’m broken” rather than “winter HRV runs lower” is a common interpretation mistake.&lt;/p&gt;

&lt;p&gt;Ninety days is enough to see one full mesocycle of training adaptation. Six months is enough to see seasonal swings. A year is enough to detect anything genuinely meaningful about how your physiology evolves.&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. This matters a lot, and consumer health apps routinely paper over it.&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. There may be a confounder — caffeine timing, meeting load, stress, food choice, alcohol — that you happen to do on the same days. Statistical correlation alone never proves cause.&lt;/p&gt;

&lt;p&gt;The right way to use correlation insights is as &lt;strong&gt;hypotheses worth testing&lt;/strong&gt;, not verdicts. If Observa flags “your sleep efficiency drops after late workouts” with high confidence, the useful response is: try training earlier for two weeks, and see if your sleep efficiency improves. That’s the only way to convert correlation into something close to causal knowledge.&lt;/p&gt;

&lt;p&gt;This 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;A lot of consumer health apps compute a single daily score: WHOOP-style 0–100 recovery, an Apple-Watch-style “Mind &amp;amp; Body Hello”, Athlytic’s recovery percentage, a Bevel-style biological age. These are useful as glanceable summaries. They’re also opaque — you have very little visibility into &lt;em&gt;what’s moving them&lt;/em&gt; day to day.&lt;/p&gt;

&lt;p&gt;The principle Observa is built on is the opposite: never a single score, always the underlying metric measured against your own 60-day baseline. “Your HRV (SDNN) is 18% below your personal 60-day baseline” tells you something. “Your recovery is 58/100” tells you something &lt;em&gt;averaged&lt;/em&gt; — and the moment you ask “why?”, the score can’t answer.&lt;/p&gt;

&lt;p&gt;This is also why 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 only meaningful comparison is &lt;em&gt;you, today, vs. you, on average, over the last two months.&lt;/em&gt; That comparison is genuinely informative. 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, mostly when you’re still — not RMSSD, the metric most sports-science tools use. The absolute numbers are not directly comparable to chest-strap measurements or to numbers from a different watch. What is comparable is &lt;em&gt;your watch’s reading of you over time&lt;/em&gt;. Tracking that SDNN reading against a 60-day mean is the right way to read it; comparing your raw number to a friend’s is not.&lt;/p&gt;

&lt;p&gt;Apple Watch also captures ECG sinus-rhythm data on Series 4 and later, which adds genuine recovery signal when interpreted in context. Sleep stage data (deep, REM, core, awake) comes from a combination of motion and heart rate variability — accurate enough for tracking trends, not accurate enough for clinical sleep staging.&lt;/p&gt;

&lt;p&gt;For the curious, &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 surfaces single-variable patterns on the free tier and multi-variable patterns on Pro. Everything runs on your device — no upload, no account, no servers. The point is to make Apple Health useful for the thing it’s quietly 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 quietly accumulating in your Health app since you got the watch. The only thing missing has ever been a layer that knew how to 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-05-13T00: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. The gap isn&apos;t ambition — it&apos;s that 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 is rarely about ambition; it’s about the manual workflow taking 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 any indie developer follow to get from one locale to 39, with the upfront cost compressed to about 90 minutes and the per-release cost reduced to about 15 minutes. The key insight is structural, not technical: 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–2 hours to build the 6 base screenshots in Figma or your design tool of choice. This is the actual creative work and it’s fine.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Localisation prep:&lt;/strong&gt; 1–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; Here’s where it gets brutal. 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 next locale, do it all again. Plan for 2–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;This is the implicit reason almost every indie app ships in one or two locales. It’s not the App Store Connect requirements that are unreasonable — Apple is right to want localised screenshots — it’s that 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;The structural shift is this: &lt;strong&gt;keep your text as a separate, editable overlay layer, never baked into the screenshot image.&lt;/strong&gt; Once you adopt this 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;The benefit compounds. 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;This is what makes the 15-minute-per-release cost work. The expensive parts (rendering, layout, upload) are mechanical compute, not 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–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–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 (Japanese typically — the character density is different 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: ~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, not 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–30 hours described above. For an app shipping 3 releases per year that’s 30–90 hours per year — half a developer-week.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Figma + AI translation (BYO API) + manual upload:&lt;/strong&gt; ~$2–5 of API calls per release. Time cost drops to 4–10 hours.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Subscription SaaS (Screenshots.pro / AppLaunchpad Pro / Screenshot Studio):&lt;/strong&gt; $19–$49 per month = $228–$588 per year. Time cost drops to 1–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–$2 per release at 2026 API prices).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The cost-of-tool is small compared to the cost-of-time. The decision is mostly about which workflow architecture you adopt, not which logo is on the tool.&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–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, never baked 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 compounding return on the first hour of architecture work is months of reclaimed time per year.&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;The 39-locale workflow isn’t about ambition. It’s about whether your text layer is editable. Get that architecture 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-05-13T00: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 goes one step further — it builds a tailored checklist for the event type and schedules each task backward from the date, so you don&apos;t have to. Here&apos;s exactly how the template engine works, why it&apos;s anchored to T-minus rather than T-plus, and what&apos;s deliberately not in it.</summary>
    <content type="html">&lt;p&gt;The reason most countdown apps stop at days is that days are easy. A date subtracts from another date and the result is 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. But the part that turns Soon. into a planner — Plan Mode — is the layer that comes after the number: a checklist of what to actually do between now and the date, tailored to the event type, scheduled backward from the date, and surfaced 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 deliberately doesn’t do, 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-slate Custom type for anything else.&lt;/p&gt;

&lt;p&gt;The templates are authored once, shipped in the app binary, and the same for every user. That is a deliberate choice and worth defending.&lt;/p&gt;

&lt;p&gt;The alternative is generation: at event-create time, send the event type and date to a server (or an on-device LLM), 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 if the model is local, the design pressure pushes toward “give the model more context so the output is better” — and the more context you collect, the more the privacy guarantee erodes. 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 authored once is the same checklist for every user. Two friends comparing notes get the same baseline. A generated checklist is a roll of the dice — sometimes it includes the rehearsal dinner, sometimes it doesn’t, sometimes it adds 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;Authoring is slow and that’s a feature.&lt;/strong&gt; Writing a good wedding template forces a human to ask “is this the seventh task or the first?” An LLM doesn’t ask that. The friction of authoring is the friction of getting it right.&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. There is no hidden layer.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So: every Plan Mode template is a list. A human-authored list. Same list 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 absolute 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 the 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;The reason for T-minus rather than calendar dates is that the template needs to work for any event date in any year. A trip in seven months and a trip in three weeks both use the same template; only the anchoring offset changes. It also turns out to be the way humans actually think about prep — &lt;em&gt;“two weeks before the wedding”&lt;/em&gt; is how you talk to your photographer, not &lt;em&gt;“July 29th.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There’s a second benefit: T-minus is what widgets render. The Lock Screen, StandBy, and Home Screen widgets all show days-to-go. T-minus is the native unit of the app, so the planning layer speaks the same language.&lt;/p&gt;

&lt;h2 id=&quot;one-notification-per-task-not-a-stream&quot;&gt;One notification per task, not a stream&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. Not one notification per day. Not one notification per event. One per task.&lt;/p&gt;

&lt;p&gt;For a trip 30 days out, the notification stream looks like this across the whole month:&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, spread over a month, each one actionable on the day it arrives. Compare that to the failure mode it replaces: a generic countdown app firing “30 days until your trip!” every morning for thirty mornings. That is noise, not signal.&lt;/p&gt;

&lt;p&gt;The free tier of Soon. doesn’t notify at all. Plan Mode is visible on the event card and the widget; the notifications layer is a Premium addition for users who want active prompting rather than passive presence.&lt;/p&gt;

&lt;h2 id=&quot;what-plan-mode-deliberately-doesnt-do&quot;&gt;What Plan Mode deliberately doesn’t do&lt;/h2&gt;

&lt;p&gt;It doesn’t auto-restructure your checklist. If you hide a task, it stays hidden — Soon. doesn’t quietly re-add it next week. If you reschedule a task from T-14 to T-21, that’s where it lives.&lt;/p&gt;

&lt;p&gt;It doesn’t share. Soon. is on-device only. Plan Mode checklists don’t sync between users, and two people planning the same wedding each install Soon. and create the event independently. (Shared events via opt-in iCloud are on the long-term roadmap; the privacy model has to stay intact.)&lt;/p&gt;

&lt;p&gt;It doesn’t optimise. There is no algorithm that watches your checklist completions and reweights the template. The template you ship with is the template you get. Personal customisation is your edits, not a model’s drift.&lt;/p&gt;

&lt;p&gt;It doesn’t surveille. Soon. has no analytics SDK, no event-completion telemetry, no “did this notification work” feedback loop reporting home. We don’t know — and don’t want to know — which tasks users check off, which they ignore, or which they reschedule.&lt;/p&gt;

&lt;p&gt;These are not features we forgot to build. They are features we considered, prototyped, and removed.&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 visible 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 one 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 is anchored to weeks (Week 28, Week 32, Week 35) rather than days because that’s how pregnancy is talked about in clinical and personal contexts. The Wedding template runs to T-90 because the long-tail prep — vendor confirmation, save-the-dates, dress fittings — starts further out than other event types. The Trip template tops out at T-30 because most trips simply aren’t planned earlier than that in practice.&lt;/p&gt;

&lt;p&gt;Those choices are author judgments, not data-driven optimisations. If they’re wrong for your event, you edit them.&lt;/p&gt;

&lt;h2 id=&quot;why-this-matters-beyond-soon&quot;&gt;Why this matters beyond Soon.&lt;/h2&gt;

&lt;p&gt;Most apps that try to do “planning” end up either (a) generic to the point of uselessness, or (b) so configurable that they require setup work users don’t want to do. The middle path is event-type-aware templates that ship with sensible defaults, are editable at the seam, and don’t try to learn anything about you.&lt;/p&gt;

&lt;p&gt;For a countdown app specifically, the engineering load of this is low. A template is a list. A T-minus offset is subtraction. The hard part is authoring the lists well — and that’s not a technical problem, it’s a writing problem.&lt;/p&gt;

&lt;p&gt;If you build planning features into a vertical app — workout, cooking, study, project — the same shape applies: ship templates, anchor them to a meaningful zero (the date, the deadline, the milestone), schedule backward, fire one prompt per task on its day, and stop there. Don’t AI it. Don’t surveille it. Don’t auto-tune it. Just ship the list.&lt;/p&gt;

&lt;p&gt;That’s all Plan Mode is.&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; 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; don&apos;t actually adapt to your games — they adapt to a generic difficulty curve over a fixed puzzle pool. 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 skill-bucket flags become a spaced-repetition training queue. No marketing. No black box.</summary>
    <content type="html">&lt;p&gt;Most chess apps that say “adaptive training” mean one of two things. They either mean “we have a difficulty slider,” or they mean “we have a recommendation algorithm over a fixed puzzle library.” Neither of those is what Chessful does.&lt;/p&gt;

&lt;p&gt;Chessful’s adaptive training adapts to &lt;strong&gt;your specific games&lt;/strong&gt;. The training 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 training queue is going to drill back-rank defenders. If you finally stopped doing that and started misjudging king-and-pawn endgames, the queue is going to start drilling opposition technique.&lt;/p&gt;

&lt;p&gt;This is the design note for how that works. The post is structured around the five stages between “you played a game” and “tomorrow’s training session is ready,” in order. Nothing here is novel computer science — it’s the application of well-understood techniques (engine analysis, rule-based classification, spaced repetition) glued together with the specific judgement calls that make the difference between a feature that works and one that doesn’t.&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;Every Chessful game ends with the position passed into a local Stockfish process running on the same device. There is no cloud call. The engine runs at a depth tuned to the device — deeper on Macs and recent iPads, shallower on older iPhones — and produces a centipawn evaluation per move.&lt;/p&gt;

&lt;p&gt;This is the part of the pipeline that most directly resembles what Chess.com, Lichess, and every other chess analyser does. It’s a commodity. The difference is that for Chessful, the centipawn output is not the product — it’s the &lt;strong&gt;input&lt;/strong&gt; to the next stage. Showing a user a centipawn graph and calling that “analysis” is what every other app does, and it’s exactly the move Chessful is structured to avoid.&lt;/p&gt;

&lt;p&gt;A note on engine depth: there’s a tempting design pressure to crank the engine deeper to find more mistakes. We chose not to. A 13-ply analysis at club level finds the mistakes that actually matter for an 800–1800 rated player; a 25-ply analysis surfaces lines that even good players can’t read. The point is to identify the patterns the user can act on, not to demonstrate engine strength.&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 diverges from every other chess analyser. The centipawn evaluation is run through a &lt;strong&gt;layered motif classifier&lt;/strong&gt;: hand-curated rule-based detectors plus a small on-device language model. The job of the classifier is to take a position where the user lost a significant amount of centipawn value and label it with one of about thirty motif categories.&lt;/p&gt;

&lt;p&gt;A non-exhaustive list of the categories:&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 your own piece’s only defender), 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. The label is chosen by the strictest matching detector — the rules are ordered and the first match wins, to avoid the failure mode where one position gets classified as five different things and dilutes the training signal.&lt;/p&gt;

&lt;p&gt;Why hand-curated rules and not a learned classifier? Two reasons. First, &lt;strong&gt;rules are auditable&lt;/strong&gt;: if the trainer is drilling the wrong pattern, we can read the rule and fix it. A learned classifier on chess motifs would be opaque — and worse, would drift between app updates as the model gets retrained, which means the user’s “improvement” might be the algorithm changing what it considers a mistake rather than the user actually improving. Second, the &lt;strong&gt;chess motif catalogue is small enough to be tractable&lt;/strong&gt;. There are roughly thirty mistake categories that matter for club players. Encoding them as rules over the engine’s output is engineering work, but it’s bounded engineering work. Training a classifier wouldn’t beat rules at a problem this constrained.&lt;/p&gt;

&lt;p&gt;The small on-device language model contributes to the explanation layer — turning the motif label and the engine evaluation into the one or two sentences the user actually reads. It doesn’t do the 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-ish motif categories maps to one of five &lt;strong&gt;skill dimensions&lt;/strong&gt;: tactics, defense, positional play, openings, endgames. When a mistake is classified, the corresponding skill bucket gets a flag. The flag includes 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;The buckets are visible inside the app. You can see exactly how many tactical motifs were flagged this week, which specific tactical motifs they were (mostly missed forks? mostly back-rank threats?), and how the count compares to two weeks ago. Premium adds long-term trend graphs (90 / 180 / 365 days) so you can see whether (say) your defense flag count is actually trending down over a quarter, or whether you’re plateauing.&lt;/p&gt;

&lt;p&gt;This visibility matters because &lt;strong&gt;adaptive training depends on the user trusting the algorithm&lt;/strong&gt;. If the next training session is drilling “back-rank threats” and the user has no idea why, the user disengages. If the user can see — “right, the algorithm is drilling back-rank threats because I made the same mistake in three of my last five losses” — the user does 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 established memory-encoding tool for pattern recognition. Anki popularised it for languages; SuperMemo formalised the underlying schedule decades ago. The mechanic is simple: positions you’ve seen recently are seen again sooner; positions you’ve solved correctly multiple times in a row drop out of rotation; positions you got wrong recently come back fast.&lt;/p&gt;

&lt;p&gt;The reason it works for chess specifically is that chess pattern recognition is a &lt;strong&gt;memory task more than a calculation task&lt;/strong&gt;. The reason a 1600 player beats a 1400 player on the same tactical position is mostly that the 1600 has seen the pattern enough times to recognise it within two seconds. Forcing the 1400 player to see the pattern repeatedly at increasing intervals is the right pedagogic move. It’s not glamorous, but it’s correct.&lt;/p&gt;

&lt;p&gt;Chessful uses a Leitner-style schedule (boxes 1 through 5, intervals roughly 1 day, 3 days, 7 days, 14 days, 30 days). A new flagged motif starts in box 1. A correct solve moves it up a box; an incorrect solve drops it back to box 1. After two correct solves at box 5, the motif graduates out of rotation — though it can come back if the same motif gets re-flagged from a new game.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Free tier: three sessions per week.&lt;/strong&gt; Three sessions is enough to cover the highest-priority bucket flags but forces the user to choose. Premium: unlimited sessions. The Premium upgrade is the right move for serious improvers; the free tier is honest 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 per-skill-dimension graphs 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 reason these graphs matter is 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 rising rather than falling, that’s a signal that the drills aren’t working — you need a different intervention. Maybe the motif you’re missing isn’t actually a defense problem; maybe it’s a calculation problem you’ve been mis-classifying. Maybe you’re tired and rushing on the drills. Maybe you’re playing in time-trouble and the motif is fine but the time management is the real bottleneck. The graphs make those questions answerable.&lt;/p&gt;

&lt;p&gt;This is the part of the engine that takes the longest to surface. Most users don’t engage with the trend graphs until they’ve been using the app for a month or two. But once they do, the trend graphs become the thing that keeps them training — because they can see the curve moving, or notice when it’s not, and respond.&lt;/p&gt;

&lt;h2 id=&quot;what-this-isnt&quot;&gt;What this isn’t&lt;/h2&gt;

&lt;p&gt;A few things adaptive training in Chessful deliberately is not:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;It’s not a replacement for studying.&lt;/strong&gt; Drilling motifs from your own games closes specific gaps, but it doesn’t replace working through an endgame book or a structured course on the Sicilian Dragon. Many improving players run Chessful alongside Magnus Trainer, Chessable, or printed books. The two layers — structured study and adaptive drilling on your real losses — compound.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;It’s not a replacement for playing.&lt;/strong&gt; You need to play games for the engine to have material to work with. Chessful provides 40 AI opponents to play against, but the training queue depends on having games to draw from. Three games is the minimum useful threshold; ten games is where the queue gets really specific.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;It’s not a replacement for live human play.&lt;/strong&gt; Chessful has no live matchmaking and isn’t planning to add it. The thesis is that the part of improvement that happens between games is under-tooled. Live play is well-tooled by Chess.com and Lichess. They’re complementary categories, not competing ones.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;It’s not personalised by an opaque AI.&lt;/strong&gt; The motif categories are explicit, the skill buckets are explicit, the spaced-repetition schedule is well-known. Nothing about the trainer is a black box — you can read what it’s 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 disclose what the algorithm does. The reason isn’t usually proprietary — it’s that “adaptive training” usually means “we picked a difficulty curve” and saying so would deflate the marketing. Publishing the algorithm is a way of saying: there’s a real mechanism here, it’s based on established techniques (Stockfish + rules + Leitner-style spaced repetition), and you can verify it works on your own games over the course of a month.&lt;/p&gt;

&lt;p&gt;It’s also a way of saying that &lt;strong&gt;algorithmic transparency is a Lagerland default&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;. The principle is the same across the catalogue: if the algorithm is the product, the algorithm should be readable.&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; Free tier covers 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 lives at &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-05-13T00: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 boasts about 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 is about why none of that helps an 800–1800 rated player improve, and why Chessful intentionally caps engine depth at the level where the mistakes that actually decide club games become visible — and not deeper.</summary>
    <content type="html">&lt;p&gt;Every chess app boasts about 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 — and not because it has to, but because, for the players Chessful is built for, deeper analysis makes the training worse.&lt;/p&gt;

&lt;p&gt;This post is the argument. It’s a contrarian position to take in chess software, where “depth” is treated as a quality metric the way “horsepower” is in cars. The position is that, below roughly 2000 rating, &lt;strong&gt;engine depth above 15 ply produces lines that the user cannot read or apply&lt;/strong&gt; — correct lines, but unteachable ones. The mistakes that actually decide games at 800-1800 are visible at depth 10-15. Deeper analysis surfaces subtleties that crowd out the actionable signal.&lt;/p&gt;

&lt;p&gt;It’s a pedagogic choice with a measurable side-effect (analysis runs fast on-device, which makes the iPhone-iPad-Mac on-device promise possible). But the pedagogy comes 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 is not a doubling of work — it’s something like 10,000-50,000× more work. Modern engines mitigate this with alpha-beta pruning, transposition tables, and aggressive heuristics, but the underlying cost growth is the reason cloud analysis exists at all: most depth-25 analyses are too expensive to run on a phone.&lt;/p&gt;

&lt;p&gt;The reason Chess.com and Lichess can offer depth 22-28 is that they run the analysis in the cloud, on rented compute, and return the result. The trade-off is the cloud round-trip (and, in Chess.com’s case, a daily quota gating the deep analyses).&lt;/p&gt;

&lt;p&gt;Chessful runs Stockfish on-device. The trade-off is the hardware constraint — an iPhone has roughly 1/50th of the compute of a desktop, and aggressive deep analysis on a phone is slow enough to be unusable.&lt;/p&gt;

&lt;p&gt;This is where most people stop the reasoning. The argument tends to be: “Chessful runs shallower because it has to; Chess.com / Lichess run deeper because they can.” Phrased like that, deeper is better and Chessful is making the best of a hardware limitation.&lt;/p&gt;

&lt;p&gt;But that argument is wrong, and not just slightly — it’s wrong in a load-bearing way that determines whether the training the app produces actually helps you improve. The real argument runs the other direction.&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. The user can read it: queen to e2 defends, knight comes in, bishop trades, queen recaptures, rook lifts to take on e6. The five-move sequence is within calculation reach for a 1400 player. They can see why Qe2 was right (it stops Nf4 from being effective), they can play through the line on a board, they can 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 whose payoff materialises ten moves later as a queen trade. The 1400 player cannot read this line. They cannot calculate to move 13 in their head; they cannot, by playing through it on a board, see why Re1 is the &lt;em&gt;right&lt;/em&gt; move rather than the longer Qe2 line that the depth-12 engine recommended.&lt;/p&gt;

&lt;p&gt;Both engine recommendations are correct. The position evaluation differs (-1.4 vs -1.9), but neither evaluation is wrong — they’re both Stockfish reading the position to their respective horizons. The question is which one is useful pedagogically.&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 doesn’t generalise to anything they can carry into the next game.&lt;/p&gt;

&lt;p&gt;This is the central pedagogic claim: &lt;strong&gt;at club level, engine depth beyond what the user can calculate is noise, not signal.&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;It’s not just that deeper analysis doesn’t help. It’s that deeper analysis actively 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” (since 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 the user’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bd3&lt;/code&gt; as a “mistake” (smaller eval drop, since the comparison is to a shorter calculation horizon).&lt;/p&gt;

&lt;p&gt;The depth-12 verdict is actually more useful. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bd3&lt;/code&gt; was a defensive misjudgement that the user can recognise and drill — they failed to see the importance of getting the queen to e2 before letting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Nf4&lt;/code&gt; get in. That’s a defender-placement motif. Drillable. Carry-able.&lt;/p&gt;

&lt;p&gt;The depth-22 verdict is technically correct but 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 internalise. It’s a fact about the position that has no behavioural consequence.&lt;/p&gt;

&lt;p&gt;If you train a player on depth-22 analyses, they learn to nod at engine output and accept that the engine sees further than they do. They don’t learn to play better moves themselves. The accuracy of the engine becomes a substitute for 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 to be calculable by a careful club player.&lt;/li&gt;
  &lt;li&gt;The mistakes the engine flags (hung pieces, missed tactics, defender-removal blindness, prophylactic skips, opposition errors) are the mistakes that actually decide games at this level.&lt;/li&gt;
  &lt;li&gt;The training drills derived from the analysis target patterns the player has any 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 club-level tactical horizon): depth 11-13.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Defensive misjudgements with consequences materialising in 3-5 plies&lt;/strong&gt;: depth 10-13.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Depth 13 covers the entire calculation horizon of a typical club player’s actual play. Going deeper finds &lt;em&gt;additional&lt;/em&gt; mistakes — but those mistakes are also additional things the player cannot fix.&lt;/p&gt;

&lt;p&gt;The trade-off lives at the top of the club-player range. Around 1800-2000, players begin to read longer engine lines reliably, and the right depth starts creeping up. By 2200, deeper analysis is genuinely useful. By 2400, players want depth 30+ because they actually can use it.&lt;/p&gt;

&lt;p&gt;Chessful’s audience is below that band. Depth 13-15 is where the mistakes live.&lt;/p&gt;

&lt;p&gt;The same idea — depth as the measure of what a player can actually use — runs the other way in puzzle design: 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 will produce the analysis in roughly 0.5-2 seconds per move on a typical mid-game position. A full 50-move game analyses in 30-90 seconds. That’s well within “I closed the app and reopened it; 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 — and the phone would be hot at the end of it. Battery cost is non-trivial.&lt;/p&gt;

&lt;p&gt;This is the side-effect of the pedagogic choice. Chessful runs analysis 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 — and would probably have to fall back to cloud analysis for older phones, which would compromise the privacy story. The reason that didn’t happen isn’t that the privacy story is more important than the training; it’s that depth 22 doesn’t produce better training. The pedagogic choice and the privacy story both happen to point the same direction.&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;This isn’t an argument against deep engine analysis in general. Deep analysis is useful for:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Players above 2000 rating&lt;/strong&gt;, where 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’re trying to identify 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 allows the player to 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 rather than human improvement.&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” rather than “what should this player do next.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For club-level improvement training, none of these apply. The training goal is to fix the patterns the player gets wrong in actual games. Those patterns are visible at depth 13. Deeper analysis surfaces additional patterns the player cannot act on.&lt;/p&gt;

&lt;p&gt;The mainstream chess software industry has settled on “more depth = better app” partly because depth is a metric that’s easy to compete on (just rent more cloud compute), and partly because the most visible chess players (titled players, streamers, content creators) actually 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’s bet is that the median user is served better 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 methodology — including how Stockfish output gets translated into motif classifications and spaced-repetition drilling — is documented 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 documented 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-05-13T00: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 — the psychology of anticipation is one of the most reliably positive emotional states a person can be in, and it costs nothing. This post is about why countdown apps work, why anticipation outperforms reminders as a motivational tool, and what a well-designed countdown should actually do with that emotional surface.</summary>
    <content type="html">&lt;p&gt;There’s a thing tourism researchers established about a decade and a half ago that everyone in the holiday-planning industry quietly knows but doesn’t talk about much: the happiest part of a vacation is, statistically, 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 the affective state of holidaymakers across the full arc of a trip — before, during, and after. The chart that came out of it 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 itself, and reliably higher than after. The post-trip dip is real. The mid-trip happiness is real. But the pre-trip ascent — the anticipation — is where the most reliable, longest-duration positive affect lives.&lt;/p&gt;

&lt;p&gt;This isn’t a quirk of holidays. It generalises. Weddings, births, graduations, moves, long-planned reunions, big concerts, retirement: any specific positive future event has the same emotional shape. The lead-up is its own reward, distinct from the event itself, and often longer-lasting.&lt;/p&gt;

&lt;p&gt;Countdown apps are a tool for harvesting that.&lt;/p&gt;

&lt;p&gt;This post is about why countdown apps work, what the research actually says about anticipation as a motivational and affective state, why anticipation outperforms reminders for this category of event, and what a well-designed countdown should do with the emotional surface it occupies on a phone Home Screen.&lt;/p&gt;

&lt;h2 id=&quot;what-the-research-actually-says&quot;&gt;What the research actually says&lt;/h2&gt;

&lt;p&gt;George Loewenstein, an economist at Carnegie Mellon, formalised the concept of &lt;strong&gt;anticipatory utility&lt;/strong&gt; in 1987 with a paper called &lt;em&gt;“Anticipation and the Valuation of Delayed Consumption.”&lt;/em&gt; The setup was disarmingly simple: subjects were asked to choose 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 choose “as soon as possible” — 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 something else. A significant fraction of subjects chose to delay the reward — not because they didn’t want it, but because they wanted to &lt;strong&gt;savour&lt;/strong&gt; the anticipation. The act of looking forward to the kiss was, for them, a source of utility in its own right. They were willing to pay (in delayed gratification) to extend the anticipation phase.&lt;/p&gt;

&lt;p&gt;This finding has been replicated and extended across many domains:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Van Boven and Gilovich (2003)&lt;/strong&gt; showed that subjects who reflected on past experiential purchases (trips, concerts, dinners) were more positive than those reflecting on material purchases (electronics, clothes). They proposed that experiences produce three distinct utility phases — anticipation, consumption, memory — and that the anticipation phase is often the strongest.&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.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Sevdalis and Harvey (2007)&lt;/strong&gt; showed that anticipation effects survive even when participants are uncertain whether the future event will happen at all — a kind of pre-emptive enjoyment.&lt;/li&gt;
  &lt;li&gt;More recent work in positive psychology calls this &lt;strong&gt;prospection&lt;/strong&gt; — the brain’s capacity to mentally simulate future positive states — and treats it as one of the four pillars of well-being (alongside connection, meaning, and engagement).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The takeaway: anticipation isn’t a side-effect of waiting for something. It’s its own form of consumption. 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 superficially similar — both surface a future event on your phone — but they operate on fundamentally different psychological frames.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;reminder&lt;/strong&gt; frames a future task as &lt;strong&gt;obligation&lt;/strong&gt;. The implicit verb is &lt;em&gt;do&lt;/em&gt;: “remember to do this thing.” The affective valence is neutral at best, mildly aversive at worst. People often turn reminders off, ignore them, or rage-dismiss them, especially when the volume is high. The reminder is a debt.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;countdown&lt;/strong&gt; frames a future event as &lt;strong&gt;reward&lt;/strong&gt;. The implicit verb is &lt;em&gt;expect&lt;/em&gt;: “this thing is coming.” The affective valence is positive. People keep countdowns visible, photograph them to send to friends, screenshot them when they hit milestones. The countdown is a savings account.&lt;/p&gt;

&lt;p&gt;This frame difference matters because the &lt;em&gt;same future event&lt;/em&gt; can be delivered through either frame and the psychological response is measurably different. “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 check at coffee in the morning reads as something you’re glad about.&lt;/p&gt;

&lt;p&gt;The point isn’t that reminders are bad. They’re the right tool for &lt;strong&gt;negative or neutral future obligations&lt;/strong&gt; — bills, recurring chores, appointments you don’t want but have to keep. Reminders are the right frame for the dentist.&lt;/p&gt;

&lt;p&gt;Countdowns are the right tool for &lt;strong&gt;positive future events&lt;/strong&gt; — the kinds where the lead-up is itself the reward. Reminders are the wrong frame for a honeymoon.&lt;/p&gt;

&lt;p&gt;Most countdown apps fail because they’re built like reminders. They render the number bigger, they ship widgets, they add a theme picker. But they treat the date as an obligation to be managed rather than an experience to be savoured. The photo is missing. The checklist is generic. The notifications fire daily. They industrialise anticipation into something that feels like work.&lt;/p&gt;

&lt;p&gt;The fix is to design for the savouring use case, not the reminder use case.&lt;/p&gt;

&lt;h2 id=&quot;what-a-well-designed-countdown-actually-does&quot;&gt;What a well-designed countdown actually does&lt;/h2&gt;

&lt;p&gt;Three components, in priority order. Get any one wrong and the app doesn’t work as anticipation infrastructure.&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. Not a stock image, not a theme background — a photo the user picked, of the specific future state. The venue, the beach, the maternity ward, the new apartment. 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;This is why the full-bleed photo background isn’t a cosmetic feature in this category. It is the &lt;strong&gt;load-bearing affective component&lt;/strong&gt;. Without it, the countdown is a number; with it, it’s a daily rehearsal of the future 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. Not a generic to-do list — a checklist that knows what kind of event this is and what the prep rhythm should look like.&lt;/p&gt;

&lt;p&gt;The reason is anxiety. A bare countdown to a wedding is often slightly anxiogenic — the user knows the date, doesn’t know the path, and the gap between those two pieces of information widens as the date approaches. A countdown that ships a plan closes that gap. The number stops being a reproach (“you should be doing something”) and starts being a coordinate (“you are 21 days out — here is what 21-days-out looks like”).&lt;/p&gt;

&lt;p&gt;The checklist also unlocks the savouring effect by giving the anticipation a &lt;em&gt;path&lt;/em&gt;. You don’t just look forward to the wedding; you cross off “send save-the-dates” and feel, fairly, like you’re already partly in it. Anticipation pairs with progress to produce a much more sustained positive affect than anticipation alone.&lt;/p&gt;

&lt;h3 id=&quot;3-a-notification-rhythm-calibrated-to-one-prompt-per-task-not-one-per-day&quot;&gt;3. A notification rhythm calibrated to one prompt per task, not one per day&lt;/h3&gt;

&lt;p&gt;The third thing a well-designed countdown does is, paradoxically, &lt;strong&gt;shut up most of the time&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The failure mode of every reminder-shaped countdown app is daily “X days to go!” notifications. The first one feels good. The second one feels okay. By the seventh one, the user has banner-banned the app. The signal-to-noise ratio of one notification per day, every day, for 90 days, is terrible. You get 90 notifications and one signal.&lt;/p&gt;

&lt;p&gt;A well-designed 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 a “buy travel adapter, check passport expiry” prompt; T-7 has “refill prescriptions.” The user gets six or seven notifications spread over a trip month, each one actionable on the day it arrives. The rest of the time, the countdown lives on widgets — Home Screen, Lock Screen, StandBy — ambient and visible without being intrusive.&lt;/p&gt;

&lt;p&gt;This is the difference between &lt;strong&gt;ambient presence&lt;/strong&gt; (good) and &lt;strong&gt;interrupt-driven presence&lt;/strong&gt; (bad). Anticipation is sustained by the former and corroded by the latter.&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 you’re building any product that involves a positive future event — a planning app, a booking app, a goal-tracker, a course-completion app — the countdown frame is probably under-used.&lt;/p&gt;

&lt;p&gt;A few specific implications:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Anywhere you currently have a “deadline” or “due date” UI, ask whether the user actually wants a deadline frame or an anticipation frame.&lt;/strong&gt; Course completion, fitness milestones, savings goals, product launches — most of these are positive future events the user is looking forward to, not negative obligations they’re managing. The UI should reflect that. A photo background on a savings goal page (the apartment, the trip, the camera) is not a gimmick. It is the affective infrastructure of the feature.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Distinguish reminder-frame and countdown-frame events at the data layer.&lt;/strong&gt; They want different defaults, different notification cadences, different visual treatments. Mixing them in one “events” model produces a UI that pleases no one.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Cap notification frequency to “task days only” by default.&lt;/strong&gt; Most users will not configure this themselves. The default has to be quiet.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Treat the run-up as the product, not as a wait state.&lt;/strong&gt; The user experience starts the moment they create the event, not the moment the event happens. Design the 30-day or 90-day run-up as a feature, not as a loading bar.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are not radical claims. They are how Loewenstein, Nawijn, Van Boven, and Gilovich’s findings translate into product design, and they apply far beyond the narrow category of countdown apps.&lt;/p&gt;

&lt;h2 id=&quot;practical-what-soon-tries-to-do-with-this&quot;&gt;Practical: what Soon. tries to do with this&lt;/h2&gt;

&lt;p&gt;The reason &lt;a href=&quot;/apps/soon/&quot;&gt;Soon.&lt;/a&gt; exists, in one sentence, is that none of the major countdown apps treat anticipation as a primary product surface. They treat it as a number to be rendered. Soon. is structured around the three components above — photo, plan, calibrated notifications — for the same reason every shipped feature in the app is structured that way: because the research-backed model of what makes a countdown valuable says that’s where the value lives.&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 — is the agency component. The full-bleed photo background is the sensory anchor. The one-notification-per-task notification rule (Premium) is the calibration component.&lt;/p&gt;

&lt;p&gt;The point of this post isn’t to sell that app, though. It’s to articulate, for anyone building products in this space, that countdown is a category worth taking seriously — not as a novelty UI element, but as an affective infrastructure for positive future events. The research is decades old. The product space is mostly still rendering numbers.&lt;/p&gt;

&lt;p&gt;There is a substantial unmet need for tools that take anticipation seriously as a primary experience. The next generation of planning, productivity, and life-events apps will be built on this premise. It’s worth starting from the psychology.&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; 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-07-11T00: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. The number on its own is one of the most-misread metrics in consumer health. Here&apos;s what HRV actually 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 quietly 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 on Heart Rate Variability. You’ll see a column of numbers from the last few weeks. Probably some are 25, some are 45, some are 80. You’ll see a “Range” chart that looks vaguely informative. You may, if you’ve fallen into the wrong corner of the internet, have read that HRV “should” be above 50ms or that anything below 30 is “concerning.” This is approximately 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 — heart-rate variability — is the variation in time between consecutive heartbeats. Apple Watch specifically 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. 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. That’s a 10× spread. The factors that move someone’s individual baseline:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Age.&lt;/strong&gt; HRV declines roughly 0.5–1ms per year after age 30 in most longitudinal studies. 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 sexes.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Fitness level.&lt;/strong&gt; Endurance-trained individuals routinely show 50–100% higher resting HRV than untrained individuals. This isn’t proportionally informative either — well-conditioned athletes often have HRV in ranges that would look “elevated” in a generic chart.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Body position.&lt;/strong&gt; HRV is higher when supine than seated, 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;In other words: 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 reading that’s reliably interpretable is 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 are statements about you against yourself. Both compensate for nearly every confounder above — age doesn’t change in 60 days, sex doesn’t change, your fitness doesn’t change dramatically, your watch is the same watch. What does change is what &lt;em&gt;moved your physiology this week relative to last quarter&lt;/em&gt;. That’s the question worth asking.&lt;/p&gt;

&lt;p&gt;Sixty days is a useful baseline window for three reasons. First, it’s roughly two menstrual cycles, so cyclical variation averages out. Second, it covers two typical training mesocycles, so transient adaptation doesn’t dominate. Third, it provides enough non-overlapping weekly samples to make a standard deviation actually meaningful — fewer than that, and the SD itself is noisy.&lt;/p&gt;

&lt;p&gt;This is the baseline window &lt;a href=&quot;/apps/observa/&quot;&gt;Observa&lt;/a&gt; uses, and it’s the same window most peer-reviewed sports-science HRV studies use 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 single 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, intense training the day before, or just normal day-to-day biological noise. It does not, by itself, mean you should rest, train hard, panic, or rejoice.&lt;/p&gt;

&lt;p&gt;What’s diagnostic is a &lt;em&gt;pattern&lt;/em&gt;. Three consecutive days more than one standard deviation below baseline is signal. A single 25% drop after a known stressor is information about that stressor, not your health. A 25% drop with no identifiable cause and no resolution within 72 hours warrants attention — but attention from a clinician, not a consumer app.&lt;/p&gt;

&lt;p&gt;The pattern threshold I think is roughly right for self-experimentation is: &lt;strong&gt;needs 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 should treat a finding as anything other than noise. Most consumer apps surface “insights” with far thinner statistical backing than this. That’s mostly why their 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 a 10–20% drop in your HRV baseline from October to February. The usual suspects: cold exposure, less daylight, less aerobic activity, more indoor time, altered sleep patterns. None of these are pathological. All of them produce the same downward drift.&lt;/p&gt;

&lt;p&gt;Reading a winter dip as “I’m broken” is one of the most common interpretation mistakes. Reading it as “winter HRV runs lower for me, here’s the new baseline to measure deviations from” is the correct response. The baseline is supposed to drift — 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 that fall out of 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, ever.&lt;/strong&gt; Not a friend’s, not a stranger’s on Reddit, not a “normal range” infographic. The comparison is meaningless. Compare yourself to yourself.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Track trends, not points.&lt;/strong&gt; A single day’s HRV is mostly noise. The 7-day rolling mean is signal. 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, not a raw number.&lt;/strong&gt; HRV is roughly log-normally distributed, so the same millisecond gap means more at a low baseline than a high one. Comparing today’s SDNN to your personal rolling mean as a percentage deviation 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, after alcohol, after high screen time, that’s actionable. The drop itself 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; Winter lower, summer higher is normal. Pandemic, illness, life stress, a new baby — all expected baseline movers. The baseline is a moving frame, not an absolute 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;. That’s the only HRV comparison that’s 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–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–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. Pathologising it 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 was always there in your Health app. The only thing that’s been missing is the frame that makes it informative.&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-07-11T00: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. Here&apos;s the practical short list: the six that actually move with your habits and reward interpretation, the twelve that look meaningful but mostly aren&apos;t, and how to tell the difference.</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’s not an indictment of Apple Health. It’s an indictment of how consumer health apps display data they don’t actually have a frame for. The trick to using Apple Health well is knowing which numbers are worth tracking against a personal baseline, and which you should stop opening the app to check.&lt;/p&gt;

&lt;p&gt;This post 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;These are the metrics where 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 stable enough baselines to make deviations meaningful.&lt;/p&gt;

&lt;h3 id=&quot;1-hrv-sdnn&quot;&gt;1. HRV (SDNN)&lt;/h3&gt;

&lt;p&gt;Heart-rate variability — which Apple Watch records as SDNN, the standard deviation of the intervals between successive heartbeats — is the single most informative metric it collects. It integrates autonomic nervous system state, recovery, training adaptation, alcohol load, sleep quality, and acute stress into one number — and changes measurably within 24–48 hours of a habit shift.&lt;/p&gt;

&lt;p&gt;Caveat: only meaningful against your own 60-day baseline. 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;Slower-moving than HRV but more interpretable. Apple Watch reports an averaged RHR that smooths nicely over a week. Useful for spotting:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Aerobic fitness trends (5–10 bpm drops over 3–6 months of consistent cardio)&lt;/li&gt;
  &lt;li&gt;Pre-illness signals (sustained 5–10 bpm above baseline often precedes a cold by 24–48 hours)&lt;/li&gt;
  &lt;li&gt;Alcohol load (RHR routinely rises 5–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;The percentage of time in bed actually asleep. Apple Watch sleep tracking is mediocre at staging but very good at total time. Sleep efficiency above 90% is excellent; consistently below 80% often indicates wind-down issues, caffeine timing problems, or anxiety.&lt;/p&gt;

&lt;p&gt;This is the sleep number that holds even when you’ve had a short night. It’s also one of the most actionable: small wind-down changes typically move it 3–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;The fraction of your night spent in slow-wave sleep. Apple Watch sleep staging is approximate, but the trend is reliable. Deep sleep is where most physical recovery and memory consolidation happen — and it’s the stage most disrupted by alcohol, late workouts, late food, and bedroom temperature.&lt;/p&gt;

&lt;p&gt;What moves it (in approximate order of impact): alcohol within 3 hours of bed (-20–40%), late workout after 18:00 (-10–20%), late large meal (-10–15%), high bedroom temperature (-5–15%), high screen exposure within 30 min of sleep onset (-5–25%).&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;The percentage your heart rate drops from daytime resting average to overnight average. A dip of 15–25% is typical; sustained dips below 10% can indicate poor sleep quality even when the headline “hours slept” looks fine.&lt;/p&gt;

&lt;p&gt;This is the metric AutoSleep popularised and almost nobody else surfaces — yet for many people it correlates more strongly with subjective recovery than total sleep duration. 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;Active calories on a daily basis are too noisy and too dependent on measurement accuracy. On a weekly basis, the rolling total is one of the cleaner load metrics Apple Health has. Useful for:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Spotting training-load creep (week-over-week increases of &amp;gt;10% predict overuse injury risk)&lt;/li&gt;
  &lt;li&gt;Identifying recovery weeks (planned drops of 30–40%)&lt;/li&gt;
  &lt;li&gt;Long-term consistency (which is what actually moves cardiovascular fitness)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Read weekly. Daily active energy 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 are the metrics that &lt;em&gt;look&lt;/em&gt; meaningful but mostly aren’t. Some are perfectly fine adherence prompts but offer no interpretation surface. Others have enough sensor error or definitional ambiguity that you’ll spend more attention on them 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;A near-perfect proxy for “did you wear your watch today.” Sensitive to phone-in-pocket vs watch-on-wrist, location (urban walkers vs suburban drivers), and what counts as a step (treadmill desks generate phantom counts). 8,000 steps mostly-deliberate beats 14,000 of urban drift; the number doesn’t distinguish.&lt;/p&gt;

&lt;h3 id=&quot;8-move-ring-closure&quot;&gt;8. Move ring closure&lt;/h3&gt;

&lt;p&gt;Adherence prompt, not interpretation. Useful for getting started; useless once you’ve internalised the habit.&lt;/p&gt;

&lt;h3 id=&quot;9-stand-hours&quot;&gt;9. Stand hours&lt;/h3&gt;

&lt;p&gt;Apple’s algorithm rewards a minute of standing per hour for 12 hours. Generously calibrated. Easy to game. 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” definition counts brisk-walk-or-above heart rate. Adequate for tracking aerobic adherence; unreliable for strength training (low 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;Genuinely useful, but moves quarterly. Don’t track weekly. The day-to-day variation in the estimate is almost entirely noise. Check monthly.&lt;/p&gt;

&lt;h3 id=&quot;12-cardio-recovery&quot;&gt;12. Cardio recovery&lt;/h3&gt;

&lt;p&gt;The 1-minute heart-rate recovery after exercise. Apple Watch’s calculation is sensitive to whether you stop moving at the right moment. Even when measured well, individual variation is high and the recovery-rate baseline shifts with fitness over months. Useful in clinical contexts; 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;Apple’s estimate of your basal metabolic rate, derived from height/weight/age/sex. It’s a formula, not a measurement. 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. Too noisy for week-over-week interpretation. Don’t pay weekly attention to it.&lt;/p&gt;

&lt;h3 id=&quot;15-headphone-audio-exposure&quot;&gt;15. Headphone audio exposure&lt;/h3&gt;

&lt;p&gt;Genuinely useful for hearing protection. Not actionable except as a “turn it down” reminder. No interpretation surface beyond “is the number 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;Same as above — useful 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. 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;Adherence number for general activity. Highly dependent on whether you live in a building with stairs. No interpretive frame.&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;The general test for whether an Apple Health metric is worth interpreting:&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; sleep efficiency signal is 5–15 percentage points. Active calories error is ±20–30%; daily active calories signal is often smaller.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Is the baseline stable across seasons / 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 this metric doesn’t change anything you’d 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, adherence, or sensor data masquerading as insight.&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;The reason most consumer health apps display 30+ metrics on a dashboard is product, not science — more numbers signal more value. The reason a useful interpretation app surfaces six of them is the opposite: more numbers means more attention spent on 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 actually reward attention, surfaces correlations between your habits and those metrics, and ignores the rest. Step count, move-ring closure, stand hours — Apple Health collects them; Observa doesn’t make you stare at them. The metrics that don’t reward interpretation don’t get a dashboard tile.&lt;/p&gt;

&lt;p&gt;For most people, getting useful self-knowledge out of Apple Health is less a tracking problem than a &lt;em&gt;subtraction&lt;/em&gt; problem. The data has been collecting itself for years. The hard part is figuring out which numbers are worth 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; — illness and fitness trend signal&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Sleep efficiency&lt;/strong&gt; — 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; — under-used recovery signal&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Active energy (weekly)&lt;/strong&gt; — 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: probably not worth your weekly attention either, unless you’re a researcher with a specific question.&lt;/p&gt;

&lt;p&gt;Getting Apple Health useful is mostly a subtraction problem. Six metrics. Sixty-day baselines. Everything else is noise pretending to be insight.&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-06-21T00: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 have two sets of rules that get apps rejected or re-uploaded: the technical specs (which sizes, how many, what format) and Review Guideline §2.3.3 (what the screen is allowed to show). Here is both — the current 2026 specifications, and what each content clause actually means in practice.</summary>
    <content type="html">&lt;p&gt;App Store screenshots get apps held up for two completely different reasons, and most guides only cover one of them. The first is &lt;strong&gt;technical&lt;/strong&gt;: wrong size, wrong format, a missing required device — App Store Connect bounces the upload before a human ever sees it. The second is &lt;strong&gt;editorial&lt;/strong&gt;: the screenshot uploads fine, then a reviewer looks at it and decides the screen isn’t showing the real app, and you get the polite “your screenshots don’t appear to show actual functionality” rejection at 2 AM the night before launch.&lt;/p&gt;

&lt;p&gt;This post covers both: the current specifications, then a working developer’s read of Review Guideline §2.3.3 — which patterns reliably pass, and which ones 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 big change to internalize first: &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. The old ritual of exporting 6.7-inch, 6.5-inch, and 5.5-inch bundles is gone.&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 6.3-inch, 6.1-inch, 5.5-inch, 4.7-inch, and 4-inch are all 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’s just no longer required.&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 front-load your strongest screenshots and treat the rest as depth.&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, confirm 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;. Now the half that the specs can’t protect you from.&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’s wording on §2.3.3 has been refined a few times since 2017, but the durable spirit is: a screenshot represents the app a user will receive. Not a future version. Not a concept. Not a marketing illustration of what you wish the app did. The actual app, in actual use.&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 actually does.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The rule, 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 largely 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. A marketing team shipped a previous version’s UI in the screenshot bundle, or used a Figma concept that hasn’t been built yet. Reviewer downloads the app, can’t find the feature, rejects. Always re-render screenshots from the actual build you’re submitting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The “concept-art” screenshot.&lt;/strong&gt; Especially common in apps with rich graphics — games, drawing apps, AR apps. The screenshot is closer to a hero shot for a website than an in-app capture. Reviewer reads it as misleading. The fix is to find an in-app moment that genuinely looks like the hero shot and capture it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. The “deleted-feature” screenshot.&lt;/strong&gt; Feature existed in version 2.4, was removed in 2.7, screenshots from 2.4 still uploaded for 2.7. Re-uploading old screenshots is one of the easier ways 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; Screenshot shows “$0.99 — limited time,” App Store listing shows $4.99. Reviewer flags the inconsistency. Best practice: either show real IAP prices that match the listing, or don’t show prices in screenshots at all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. The “fictional metric” screenshot.&lt;/strong&gt; Common in fitness, finance, and analytics apps. Screenshot shows “247,891 active users this month” or “+42% sleep score” but the demo data in the app shipping today shows different numbers. 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, then inherit §2.3.3 on top.&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–12 Mbps or ProRes 422 (HQ), 30 fps, AAC audio.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then the content rule, with teeth: the video must be &lt;strong&gt;actual app footage captured from a device&lt;/strong&gt; — not a screen-recorded mockup, not an animated concept reel, not external camera footage of someone holding a phone. Apple checks this rigorously, 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; It’s tempting to reuse screenshots when only minor UI changes happened. Each time you do this you risk inheriting a rejection from a feature that quietly went away.&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. Show feature value rather than price.&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 the visual style that fits your brand — 3D Metal render, flat outline, tilted angle, transparent background, no frame at all. Reviewers don’t care about the frame. They care about what’s on the screen inside it.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The reason a capture-first tool like &lt;a href=&quot;/apps/mockly/&quot;&gt;Mockly&lt;/a&gt; is structurally compliant with §2.3.3 by default is that the 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; the frame is just a render placed around it. The reverse — mock up a concept screen in Figma, drop it into a phone outline, export — is the workflow most likely to drift into rejection territory, because it encourages designing screens that aren’t in the app 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–10 screenshots&lt;/strong&gt; per localization, PNG or JPEG, flattened. First 2–3 show in search — front-load them.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;§2.3.3 is about the screen content, not 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–30 seconds, 886 × 1920 on iPhone — 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 risk drift.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the surrounding workflow, 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; go deeper. The specs change with each new device; the §2.3.3 spirit has held for nearly a decade. The rejection emails keep arriving because most indie pipelines make compliance an afterthought instead of the default.&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-05-13T00: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 turns it into one of about thirty specific mistake categories — each with a name, a structural cause, and an explicit drill that fixes it. This post is the full catalogue. It doubles as a reference page for Chessful users and a short tour of the mistakes that actually decide club-level games.</summary>
    <content type="html">&lt;p&gt;When the prior 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 straightforward: &lt;em&gt;what are the motif categories?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Fair question. The post described the pipeline but treated the motif catalogue as a black box of “about thirty categories.” This post opens that box. Below 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 pedagogy — what’s documented in Aagaard’s &lt;em&gt;Excelling at Chess&lt;/em&gt; series, Yusupov’s &lt;em&gt;Build Up Your Chess&lt;/em&gt; nine-volume 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 specific to what an analyser running on top of your full game history can detect that a human coach reviewing one game cannot. Most of the rest is standard improvement material wrapped in a name a club player can carry into the next game.&lt;/p&gt;

&lt;p&gt;The reason it’s worth publishing the catalogue is that &lt;strong&gt;algorithm transparency is the only way to argue with an algorithm&lt;/strong&gt;. If you don’t know what Chessful’s classifier is looking for, you can’t tell whether it’s flagging the right thing about your game. If you can read the catalogue, you can.&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;Tactical motifs are the ones where the mistake was a calculation or pattern-recognition failure on a forcing sequence. They tend to be the most actionable category — drillable, fast to recognise, and reliably re-encountered across openings.&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 a piece) onto a square where it can be captured for nothing, or for less than it’s worth. Drilling pattern: piece-safety scans on the position before committing 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 have moved to a square attacking two of your pieces simultaneously, winning material. Drilling pattern: knight-radius blindness — recognising 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 in a way that left another piece behind it unable to move (or unprotected if it did move). Drilling pattern: file/diagonal awareness 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, forcing it to move and capturing the less valuable piece behind. Drilling pattern: piece-alignment awareness — particularly for back-rank rooks and same-diagonal queens.&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 to reveal an attack from another piece behind it — often combined 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;A single move attacking two distinct enemy pieces or squares, not necessarily a fork. Drilling pattern: simultaneous-threat detection.&lt;/p&gt;

&lt;h3 id=&quot;7-missed-deflection&quot;&gt;7. Missed deflection&lt;/h3&gt;

&lt;p&gt;A piece had to be lured off a critical defensive square, and the deflecting move was available but not played. Drilling pattern: identifying which enemy piece is over-loaded (defending multiple squares) and finding 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; a single attack forced the choice and won material. Drilling pattern: counting attackers and defenders on every critical square before committing.&lt;/p&gt;

&lt;h3 id=&quot;9-back-rank-threat&quot;&gt;9. Back-rank threat&lt;/h3&gt;

&lt;p&gt;Your king’s escape squares were blocked by your own pieces, and a back-rank mate was available but not seen (in either direction). Drilling pattern: prophylactic h-pawn pushes; recognising rook + 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) creates a mate when the king’s escape squares are blocked by its own pieces. Less common but reliably decisive when it appears.&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;Defensive motifs are the most under-trained category among club players. Generic puzzle apps drill tactical attacks; defensive recognition is what costs games at the 1200–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 the back rank, often a king-adjacent square). Drilling pattern: before any capture or trade, identify whether your piece is currently defending something. This is the single 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) without compensating for the structural weakness. 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 materialised three moves later. Drilling pattern: looking for the opponent’s plan before formulating 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 enough activity in return. Drilling pattern: pawn structural awareness — identifying which pawn moves create 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 initiated removed your own defensive piece and left a critical square undefended. Distinct from defender-removal blindness because the trade was voluntary. Drilling pattern: post-trade defender count.&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 are the slowest to drill but produce the most durable improvement. They generalise across openings.&lt;/p&gt;

&lt;h3 id=&quot;16-wrong-piece-traded&quot;&gt;16. Wrong piece traded&lt;/h3&gt;

&lt;p&gt;You exchanged a piece that was structurally important (a good bishop, an active knight) for a less important enemy piece. Drilling pattern: piece-quality assessment 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 queenside or kingside when the opposite would have been safer based on pawn structure or piece placement. Drilling pattern: pre-castling structural review.&lt;/p&gt;

&lt;h3 id=&quot;18-weak-square-allowed&quot;&gt;18. Weak square allowed&lt;/h3&gt;

&lt;p&gt;You allowed an enemy piece to reach an outpost square (often c4 / c5 / d4 / d5 / e4 / e5 / f4 / f5) where it couldn’t be challenged. Drilling pattern: identifying outpost squares 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 the central tension or creates an attacking path) was either delayed too long, mistimed, or played in the wrong direction. Drilling pattern: recognising the canonical 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;The Chessful-specific motif — you spent disproportionate clock time on a move that didn’t deserve it (often a recapture that was forced, or a routine developing move), leaving you with too little time for a critical decision later. Drilling pattern: time-budgeting per move. Only flagged in games where a clock is on.&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 are the most user-specific category — they depend on what repertoire the user actually plays. Chessful builds a profile of your most-played opening lines over time and flags deviations.&lt;/p&gt;

&lt;h3 id=&quot;21-repertoire-drift&quot;&gt;21. Repertoire drift&lt;/h3&gt;

&lt;p&gt;You deviated from your usual opening setup in a way that lost a tempo, allowed an early piece exchange you don’t normally allow, or transposed into a structure outside your repertoire. Drilling pattern: opening-line review focused on the deviation point.&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 would have been the principled move; you played a reasonable-looking but non-book alternative that gave up an advantage the book line preserves. Drilling pattern: book-line study on the 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;You played a sequence of moves that, by transposition, reached a position known to be inferior — often because the move order swapped a critical defensive resource. Drilling pattern: transposition-awareness for 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 technically distinct — they’re the ones where pattern recognition has to be paired with concrete calculation, and where small mistakes are most likely to convert 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 yielded) the opposition in the wrong direction, allowing the opposing king to either advance with its pawn or block your advance. Drilling pattern: opposition technique on 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 activate in time for the endgame — it sat passively on the back rank while the opposing king moved to the centre and the position simplified into a lost king-and-pawn race. Drilling pattern: identifying the point in a middlegame where king activation 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 placed your rook passively (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 converted a winning endgame into a draw by playing a move that simplified to a known-drawn structure (often wrong-color bishop, or a fortress). Drilling pattern: recognising drawn endgame structures before simplifying 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 the promotion square of your passed pawn. Often combined with drawn-but-played-on. Drilling pattern: pre-trade endgame projection.&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 specific technique (Lucena, Philidor, square-of-the-pawn, key-square calculation) was available and known to be winning, but the technique wasn’t executed correctly. Drilling pattern: drilling 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;Same as the K+P version but for rook endgames — the technique (Lucena bridge, Philidor third-rank defence, short-side defence) was the right one but executed incorrectly. Drilling pattern: rook-endgame technique-specific repetition.&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 maps to exactly one of the five skill buckets (the dimension it appears under above). When Chessful flags a motif in one of your games, the corresponding skill bucket gets a flag. The spaced-repetition queue pulls from the flagged buckets — most-recently-flagged first, with Leitner-schedule intervals between repeats.&lt;/p&gt;

&lt;p&gt;The reason the bucket layer exists between motif detection and the training queue is that &lt;strong&gt;patterns generalise within a skill dimension better than they generalise across dimensions&lt;/strong&gt;. If you keep missing forks, drilling more fork puzzles is the right intervention. If you alternate between missing forks and misjudging endgame opposition, those are different cognitive failures and need to be drilled separately — not bundled into a generic “tactics-and-endgame practice” queue.&lt;/p&gt;

&lt;p&gt;That’s the whole reason for skill dimensions. They aren’t display categories; they’re the level at which spaced repetition is scheduled.&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 explicitly does not detect:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Time-pressure tactics.&lt;/strong&gt; A blunder under thirty seconds on the clock often isn’t a pattern problem — it’s a time-management 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) rather than 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’re playing the Najdorf Poisoned Pawn variation and miss a move-20 nuance, Chessful flags it as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;repertoire drift&lt;/code&gt; rather than as a positional or tactical motif. The correct intervention is opening study, not pattern drilling.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Psychological mistakes.&lt;/strong&gt; Resigning prematurely, accepting a draw in a winning position, playing too aggressively when ahead — Chessful doesn’t try to detect these because they’re hard to disambiguate from objective mistakes from engine output alone.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These exclusions aren’t oversights; they’re the cases where motif-based drilling isn’t the right intervention, and where Chessful would mislead the user by pretending otherwise.&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 isn’t frozen. Two things change between app versions:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;New motifs get added&lt;/strong&gt; when a recurring mistake pattern appears in user games that the existing rules don’t catch cleanly. The most recent addition (v1.4) was &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;weakening pawn push without compensation&lt;/code&gt; — previously folded into king-safety underestimate, split out because the drilling patterns are genuinely different.&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 distinct training value. Splits and merges are conservative — they only happen when the resulting training queue would meaningfully differ.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All changes are logged in the app’s changelog with the motif name and the version. The spaced-repetition queue doesn’t reset on a taxonomy change — flagged positions migrate to the closest equivalent motif under the new taxonomy.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;The catalogue above is what Chessful is currently looking at when it tells you “you played Nxd5; the knight was your only back-rank defender.” That sentence is the surface; the motif label underneath it 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;; the next training session draws from that bucket using spaced repetition.&lt;/p&gt;

&lt;p&gt;The whole machine is open to inspection. That’s the point of publishing 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 methodology behind the catalogue is documented 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 at &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 — 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-05-09T00: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. None of the operations ever leave your machine. This post is the case for that — and 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. It is also, in 2026, 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 the persistent dominance of CloudConvert, Zamzar, Smallpdf, and the rest exists not because the local primitives are missing but because nobody had bothered to consolidate them 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 the contribution MediaKit makes is real but it is also limited, and it would be dishonest to claim otherwise.&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 of these are first-party Apple frameworks shipped with macOS. Specifically:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;AVFoundation&lt;/strong&gt; handles every video and audio operation MediaKit performs. Compression, conversion, trimming, merging, frame-accurate cuts — all of it.&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. None of it is proprietary to the studio. The frameworks have been on every Mac for years. They are sandboxed, hardened-runtime-safe, and have been optimized for Apple Silicon since the M1 launched.&lt;/p&gt;

&lt;p&gt;What MediaKit does is wire them together. One app. One drag-and-drop surface. One menu bar item. Six Shortcuts actions. 133 distinct tools mapped against the formats and operations a normal Mac user actually wants — instead of five separate utilities, each with its own settings panel, license model, and update cadence.&lt;/p&gt;

&lt;p&gt;That’s the whole bet. The bet is &lt;em&gt;consolidation&lt;/em&gt;, not &lt;em&gt;novelty&lt;/em&gt;. I am going to keep saying this honestly 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;A few reasons, and they are worth being clear about because they are also the reasons MediaKit needs to be a specific shape:&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 — never a 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 is specifically a response to this. Drop any file, 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. The privacy cost is invisible. The cost only becomes legible 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-forever tier is five tools: &lt;strong&gt;Video Compress, Image Compress, Image Resize, Audio Convert, PDF Compress.&lt;/strong&gt; 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, forever, with no nag screen, no countdown, no 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. There is no subscription you can forget to cancel — Pro is a one-time purchase.&lt;/p&gt;

&lt;p&gt;Pricing the free tier this way is, in the indie Mac segment, slightly unusual. Handbrake is free. ImageOptim is free. Keka is 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 — not as a trial-extension trick, but as the actual long-term offer. If you only ever compress videos and convert HEIC, MediaKit costs you nothing, forever, 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 the free user into a Pro user — those are different users.&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 I have learned to write them:&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), not editorial. 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 &lt;em&gt;recognition&lt;/em&gt; 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), three days unlocked for everything else, and never leaves the machine. That’s the whole pitch this weekend.&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-08-14T00: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 is the small essay on why a calm daily planner had to be a native Mac app — not 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. The day I’d actually like to have has nine. Somewhere in between is where the work happens — and the device I do the work on has, until this week, not been the device my planner ran 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 is the small Saturday essay on why that was the missing piece, and what I did and did not do to make it work.&lt;/p&gt;

&lt;h2 id=&quot;the-catalyst-escape-hatch-i-did-not-take&quot;&gt;The Catalyst escape hatch I did not take&lt;/h2&gt;

&lt;p&gt;Apple has been generous, for the last several years, about how easy it is to bring an iPad app to the Mac. Click a checkbox in Xcode, set a few capabilities, fix the obvious touch-target sins, ship. A lot of indie planners and to-do apps live on the Mac this way. They are, structurally, an iPad window with a menu bar.&lt;/p&gt;

&lt;p&gt;For an app you open once and dismiss — a calculator, a unit converter, a one-off utility — Catalyst is fine. For an app you keep open in a corner of the screen for eight hours, alongside Slack and your calendar and the document you’re actually trying to finish, it is not. The pixels read wrong. The keyboard shortcuts feel pasted on. The window doesn’t behave the way a Mac window behaves.&lt;/p&gt;

&lt;p&gt;So I did not Catalyst this. Taskful Day on Mac is a SwiftUI app built for the Mac first, with AppKit underpinnings where SwiftUI doesn’t yet give us the affordances a real Mac app needs. The window resizes the way you expect. The keyboard shortcuts are real Mac shortcuts. The menu bar is populated. Drag-and-drop works the way macOS drag-and-drop is supposed to, including into and out of other apps. There is a real menu bar item for quick capture without opening the main window.&lt;/p&gt;

&lt;p&gt;It took longer than Catalyst would have. It is, I think, the correct shape.&lt;/p&gt;

&lt;h2 id=&quot;one-universal-purchase-not-three&quot;&gt;One Universal Purchase, not three&lt;/h2&gt;

&lt;p&gt;The other decision worth being explicit about: 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. There is no separate Mac SKU.&lt;/p&gt;

&lt;p&gt;This is not the default. Many indie apps charge separately for the Mac version, and there are legitimate reasons to — the Mac app is often a substantial chunk of additional work, and the audience is smaller, so a per-platform price compensates. I am not arguing those teams are wrong.&lt;/p&gt;

&lt;p&gt;But for a planner specifically, asking the user to pay twice misses what the app is for. The whole point of Taskful Day is that the day you plan on one device is the day you finish on another. Splitting that across two purchases — pay for the planning surface, pay separately for the doing surface — would make the pricing model contradict the product.&lt;/p&gt;

&lt;p&gt;So: one purchase, every device. Universal Purchase has been around since 2020; this is one of the cases where it actually makes the right shape easy.&lt;/p&gt;

&lt;h2 id=&quot;icloud-not-someone-elses-server&quot;&gt;iCloud, not someone else’s server&lt;/h2&gt;

&lt;p&gt;Sync is the other place a planner can fail quietly. The day plan you make on your phone has to be on the Mac, and the focus session you ran on the Mac has to show up in the iPhone widget, and none of this should happen on 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 in this loop. I cannot see your tasks. I cannot lose your tasks 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, end of story.&lt;/p&gt;

&lt;p&gt;This is structurally different from the way most cross-platform planners work. The typical model is: sign up for an account, your tasks live on the company’s servers, the apps are clients. The studio does not run that model anywhere in the catalogue, and I am not running it here. The trade is that you cannot share a task list with a teammate through Taskful Day, because there is no shared cloud surface to share through. If that’s a workflow you need, the app is the wrong shape for you and I’d rather you use something else.&lt;/p&gt;

&lt;h2 id=&quot;what-does-now-on-mac-actually-unlock-for-taskful-day&quot;&gt;What does “now on Mac” actually unlock for Taskful Day?&lt;/h2&gt;

&lt;p&gt;Three things, specifically, that the Mac app changes in practice:&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 into the day that Taskful Day offers — 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 drop into a session at your desk, the rest of the desktop dims, the menu bar shows the countdown, and the iPhone is free to be 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, is closer to two minutes of actual writing on a real keyboard. That changes what shows up in it, which changes what the pattern view shows you a month later.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The iPhone app is still the right device for capture — you think of something, you tap, you talk, it’s filed. The iPad is still the right device for the morning review. The Mac is now the right device for the actual work, and the planner sits next to the work.&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;A quick note for users 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. Taskful Day is not GTD. Things assumes you want a project tree that lives forever. Taskful Day 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 correct and Taskful Day is not.&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, Eisenhower matrices. Taskful Day deliberately does less. There is no habit tracker, no Pomodoro per se (the focus mode is more immersive than Pomodoro), no team features. Less surface area is the point.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Sorted³.&lt;/strong&gt; Sorted is a fantastic time-blocked planner. If you live in time-blocks specifically — meaning, every task gets a start and end — Sorted is the better tool. Taskful Day’s Day Clock view does some of this, but the design philosophy is “realistic plan you can finish,” not “schedule every minute.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are good calm-design planners in this space and Taskful Day is not the only one. It is, as of this week, 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 — focus session timer, advanced analytics, widgets, iCloud sync, 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;If you are looking for the studio’s broader take on 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; is the long-form argument for the design choice you’re already feeling in this app.&lt;/p&gt;

&lt;p&gt;The next entry, on Saturday, is on 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. It will, I expect, 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-25T00: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. There is 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. Once. Here&apos;s 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;If you only read one thing about it, read this: &lt;strong&gt;there is no subscription.&lt;/strong&gt; Seven days free, no card on file. After that, you choose a one-time tier between $9.99 and $39.99 and you own the app. No auto-renew. No trial trap. Your training history is never held hostage by a lapsed subscription.&lt;/p&gt;

&lt;p&gt;The rest of this post is about why I built LiftLog this way, and what I’m trying to learn by doing 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. The whole point is that you keep showing up, week after week, year after year, and the data you accumulate — 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. The implication is straightforward: you stop paying, you lose the app, you often lose access to your own history. I find this morally awkward. The user generated the data. The user’s effort produced the personal records. Charging rent on someone’s own training journal feels like the wrong shape for the relationship.&lt;/p&gt;

&lt;p&gt;I’m not naïve about the economics. Subscriptions smooth revenue, they fund support, they pay for ongoing development. There are good reasons services like Strong, Hevy, and Fitbod use them — and I don’t think those teams are doing anything wrong. But I wanted to find out whether a different shape 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 LiftLog is genuinely the cheapest version of the app you can justify, this is the right choice. No guilt, 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 amount of your training time and feels like the tool you’ll keep using, this is the calibration most users will land on.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Generous — $29.99.&lt;/strong&gt; A step up for users who want the work supported, or who have benefited from indie software in the past and choose to lean in.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Patron — $39.99.&lt;/strong&gt; The top tier. Same app, no extra unlocks. This tier exists so people who want to back the studio at a level closer to a year of competitor subscriptions have a way to do that — without it being awkward, hidden, or a tip jar.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All four tiers unlock the same product. No content gating, no “premium” features behind a higher number. The choice is about what LiftLog is worth to you, not about which features you get.&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 ever read on charitable giving and pay-what-you-want pricing says the same thing: when you give people too many options, they freeze, and when they freeze, the median paid amount drops. Four tiers gives people meaningful agency 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 rather than top-end — and a meaningful number of users will choose to support the work above the median. That’s the bet.&lt;/p&gt;

&lt;p&gt;The labels matter too. Calling the tiers &lt;em&gt;Fair / Good / Generous / Patron&lt;/em&gt; — instead of &lt;em&gt;Basic / Standard / Plus / Pro&lt;/em&gt; — does something I want this app to do everywhere: it removes the implication that more money buys you more app. It doesn’t. It buys the studio more runway. That distinction should be honest, not obscured.&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 I’ve already had two friends ask:&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, no-card, no-pressure — but after that the app does ask you to choose a tier. I am not Strava-ing my way into a freemium grind. The trial is real; the purchase is real.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;It’s not a stunt.&lt;/strong&gt; I’m not running this as a one-week marketing experiment. Pay-what-you-can is the app’s pricing model, full stop. 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’s not infinitely scalable.&lt;/strong&gt; This 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 not arguing this should replace subscriptions everywhere — only that there’s room for it in places where it fits.&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; the price is $39.99 lifetime or $17.99/year. That app is not going anywhere. 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. This is the app for lifters who care how their tools feel, not just 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 + 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 between them, the heuristic is simple: want to log from Apple Watch → GymLogger X. Live on iPhone and want polish → LiftLog. Want to support an indie studio’s pricing experiment → LiftLog at the Patron tier. None of these are wrong answers.&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’m going into this honestly uncertain about the outcome. 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, that tells me the anchoring isn’t doing its job 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–15%. Removing the card requirement reduces friction, but it also removes the auto-renew lock-in that drives 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 meaningful Patron volume comes 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 most about. If users find the tier ladder respectful and unusual, the model is working as intended. If it feels gimmicky or guilt-trippy, it’s not — 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. Honest numbers, including the bad ones if they’re bad.&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;. Seven days, no card, full access. 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 your thing, &lt;a href=&quot;/apps/gymlogger-x/&quot;&gt;GymLogger X&lt;/a&gt; is right there at $39.99 lifetime. Same studio, same privacy principles, different shape.&lt;/p&gt;

&lt;p&gt;Either way, your training history stays on your device, no third-party tracking, no advertising SDKs, no required account. The app is small. The studio is one person. The principles aren’t going anywhere.&lt;/p&gt;

&lt;p&gt;That’s the whole thing.&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; Free for seven days, no card required. After the trial: $9.99, $19.99, $29.99, or $39.99 — one-time, you choose.&lt;/p&gt;
</content>
  </entry>

  <entry>
    <title>A calm 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-25T00: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. Your designer doesn&apos;t either. Your spouse, your co-founder, your weekly bookkeeping flow — none of them need to be able to change your app&apos;s metadata in order 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 doing the quiet financial reconciliation that the season demands.&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 exact moment. It is the smallest, simplest tool in the catalogue. I am, surprisingly often, asked 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 App Store Connect’s &lt;em&gt;write&lt;/em&gt; surface, the part where you edit metadata and 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;The reason there are two apps, and not one, is a structural permissions problem most indies hit eventually.&lt;/p&gt;

&lt;p&gt;App Store Connect has a single, monolithic role model. Either someone has access to your developer account, or they don’t. Sub-roles exist (Admin, Developer, Marketing, etc.) but the specifics are coarse — Marketing can edit metadata; Finance can read sales reports; 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;This means: if you want your accountant to see your revenue numbers, you have to give them an account on App Store Connect, configure their role, accept that they can see things you’d rather they didn’t, and trust them to log in to a developer-account web tool every time they want to check.&lt;/p&gt;

&lt;p&gt;In practice, what most indies do is ship a screenshot of their numbers via Slack or iMessage. This is fine for one-off requests. It’s terrible for any kind of regular reporting cadence.&lt;/p&gt;

&lt;p&gt;AppMeta Pulse was first pitched as the answer. It turned out narrower: a fast, calm 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;The bet behind AppMeta Pulse is that the &lt;em&gt;most-asked-for&lt;/em&gt; thing — &lt;em&gt;“how is the app selling this week?”&lt;/em&gt; — should be its own glanceable tool, separate from the editorial surface 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 surfaces:&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;It does not surface anything you can edit, apart from replies to customer reviews, which arrived at the end of April 2026. There is no metadata editing, no build management, no submission. It cannot do those things, and that’s the whole point.&lt;/p&gt;

&lt;h2 id=&quot;why-glanceable-matters&quot;&gt;Why “glanceable” matters&lt;/h2&gt;

&lt;p&gt;The form factor is iPhone, and the design is glanceable on purpose.&lt;/p&gt;

&lt;p&gt;AppMeta does the desk work — the multi-locale metadata editing, the keyword analysis, the review replies — and lives on the Mac. AppMeta Pulse does the &lt;em&gt;check-in&lt;/em&gt; — the morning coffee, the weekly meeting with a co-founder, the quarterly review with the accountant — and lives on the phone.&lt;/p&gt;

&lt;p&gt;The use case I designed for is: indie developer in a coffee shop, picks up phone, taps Pulse, sees the last seven days’ proceeds against the seven before, decides whether to pay attention or get on with the day. This should take three seconds. It does.&lt;/p&gt;

&lt;p&gt;The widget is, predictably, the surface 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 that matter at a glance.&lt;/p&gt;

&lt;h2 id=&quot;what-about-sharing&quot;&gt;What about sharing?&lt;/h2&gt;

&lt;p&gt;A use case this post originally claimed for AppMeta Pulse is &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 working on a profit-share, an accountant doing quarterly bookkeeping — these people need to see numbers. They don’t need to be able to change your app’s pricing.&lt;/p&gt;

&lt;p&gt;Pulse doesn’t do this. It has no shared access tokens and no way to give another person access to your account’s data; you can export a CSV of a period’s sales and send it yourself. The clean way to give someone ongoing read access remains 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 pricing is intentionally low. The argument: this is not a tool a studio uses for hours a day; it’s a tool you check briefly and rely on. Pricing it like a productivity-software flagship would mismatch its actual position in the indie’s stack. A one-time lifetime price puts it firmly in the “buy it and forget about it” tier, which is the right tier for what it does.&lt;/p&gt;

&lt;h2 id=&quot;what-this-is-not&quot;&gt;What this is not&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 not do tax-related 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;It is also not 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;What Pulse does is one thing: surface your App Store revenue in a glanceable way, on your phone. That’s the whole pitch.&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;This is, by my count, the third post this quarter about a tool aimed at indie iOS developers. It’s also the last for a while — I want to come back to the consumer apps that occupy most of the catalogue, and the next few weekends will probably do that.&lt;/p&gt;

&lt;p&gt;But for the indies who read this far, &lt;a href=&quot;/apps/appmeta-pulse/&quot;&gt;AppMeta Pulse&lt;/a&gt; might be the small, useful, pay-once tool you didn’t know you wanted. If you keep opening App Store Connect just to see how yesterday went, this is the better answer.&lt;/p&gt;

&lt;p&gt;Spring is the season of clean books. Use it.&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-08-14T00: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 quietly growing, TheWait has been fully rebuilt and relaunched as Soon. Here&apos;s 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, you watched the days tick down, and that was the whole deal. Over a year, it grew: widgets, themes, calendar sync, photo backgrounds. But the name — &lt;em&gt;TheWait&lt;/em&gt; — kept holding it back.&lt;/p&gt;

&lt;p&gt;In April 2026, I fully rebuilt and rebranded the app as &lt;strong&gt;&lt;a href=&quot;/apps/soon/&quot;&gt;Soon.&lt;/a&gt;&lt;/strong&gt;. New name, new icon, new home. Here’s why.&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; tells you what the app is about in a literal sense. You’re waiting. The app counts down.&lt;/p&gt;

&lt;p&gt;But that framing gets the emotional point exactly wrong.&lt;/p&gt;

&lt;p&gt;Countdown apps aren’t really about waiting. They’re about &lt;strong&gt;anticipating&lt;/strong&gt;. There’s a difference. Waiting is passive — it’s a word associated with delay, patience, endurance. Anticipating is active — it’s a feeling you cultivate, a joy you borrow from the future. When you’re counting down to a trip, a wedding, a birth, or a milestone, you’re not stuck in the wait. You’re already partly there.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Soon.&lt;/em&gt; captures that better. The period at the end is deliberate — it’s a full sentence, a quiet statement. The thing you’re looking forward to isn’t far. It’s Soon.&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;This wasn’t a simple name swap. The entire 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 ships with a smart timeline and checklist tailored to the event type. Trips get packing lists and transport reminders. Weddings get their own rhythm. You don’t have to build your own checklist — the app knows what a birthday, wedding, or graduation typically needs, and it assembles the prep automatically.&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, timeline. Your most anticipated moment can now be visible 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; When a countdown ends, it doesn’t disappear. It becomes a memory, and Soon. quietly brings it back on every anniversary. The moment never fades — it just cycles.&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. The dates you already track become the moments you can feel.&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;p&gt;The philosophy didn’t change. Soon. is still:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Private by default.&lt;/strong&gt; No ads, no tracking, no 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. No auto-charging without 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 broader &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, your themes, your data — it all migrates automatically. You’ll see the new name, the new icon, the new Plan Mode, and you’ll have access to 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;I’ll be honest: renaming an app is terrifying. App Store rankings reset. Existing users get confused. Some coverage dies on the old name. For a year I resisted doing it.&lt;/p&gt;

&lt;p&gt;But a wrong name is a daily tax. Every person who sees your app sees the wrong framing. Every conversation starts with explaining. Every review mentions the oddness. Eventually, you realise the cost of keeping it outweighs the cost of changing it — and the cost of changing it is mostly just courage.&lt;/p&gt;

&lt;p&gt;For apps in this category — countdown, anticipation, 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 quietly wrong, this is 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-25T00: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. Here they are, from fully random to hand-picked, followed by how to combine them.&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, and each of its sections runs on rules worth knowing.&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;a-routine-that-uses-all-of-it&quot;&gt;A routine that uses all of it&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;What the app does not try to replace is the website. If what you want is specifically a random featured article, the RandomInCategory address above is the most direct route there is.&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-04-04T00: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. Here is the bill-calendar method the CFPB recommends, a worked example on a real 2026 pay schedule, and the formula that makes biweekly pay behave.</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;A worked example. 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;&lt;strong&gt;A bill calendar shows which paycheck pays which bill.&lt;/strong&gt; A balanced month can still hide one overloaded fortnight.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Plan around pay-by dates, not due dates.&lt;/strong&gt; The CFPB suggests 2 to 3 days early online and at least 7 days early by mail.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Biweekly pay drifts.&lt;/strong&gt; 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;&lt;strong&gt;The smoothing formula is monthly bills × 12 ÷ 26.&lt;/strong&gt; Move that much to a bills account every payday, and seed it with one transfer.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Card due dates are fixed by rule:&lt;/strong&gt; same day every month, statement 21 days ahead, cut-off no earlier than 5 p.m.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Paid within 30 days, an account is usually still reported current.&lt;/strong&gt; 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-09T00: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. The convenience is real. The privacy implication is not small. 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;Pick the most recent moment in the last week when you needed to convert a media file. A HEIC photo to JPG, a video compressed for Slack, a PDF merged with another PDF, a screen recording’s audio extracted to MP3.&lt;/p&gt;

&lt;p&gt;If you’re like most users, you used a free online converter. You uploaded 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. You waited. You downloaded the result. You moved 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. The convenience is real, but the privacy posture is structurally wrong, and &lt;a href=&quot;/apps/mediakit/&quot;&gt;MediaKit&lt;/a&gt; is the studio’s argument that the entire category of conversion tools belongs on your Mac instead.&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, here is what the file does, in sequence:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Leaves your machine, encrypted in transit.&lt;/li&gt;
  &lt;li&gt;Lands on the operator’s storage, sometimes encrypted at rest, sometimes not.&lt;/li&gt;
  &lt;li&gt;Is processed by their conversion pipeline. The processing typically takes seconds.&lt;/li&gt;
  &lt;li&gt;Is held in storage, often for hours, sometimes for days, depending on the operator’s retention policy.&lt;/li&gt;
  &lt;li&gt;Is downloaded back to you.&lt;/li&gt;
  &lt;li&gt;&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;The first and last steps are the ones the user notices. The middle ones are the ones with privacy implications. 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;I’m not suggesting any particular online converter is malicious. Most are run by small teams and most try to delete files promptly. I am suggesting that the &lt;em&gt;architecture&lt;/em&gt; — files leaving your machine for processing tasks that don’t require it to leave — is wrong by default, and the user should not have to trust the operator to be the right kind of careful.&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;The honest historical reason cloud converters dominated is that local conversion was 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 just faster, even with the upload time.&lt;/p&gt;

&lt;p&gt;Apple Silicon erased that gap. Modern Macs have hardware video encoders that compress at multiples of real-time speed. ProRes acceleration, HEIC encoding, AV1 decoding, all of it on-die. The local performance is now competitive with — and sometimes faster than — the cloud round-trip.&lt;/p&gt;

&lt;p&gt;For images and PDFs, local processing was always faster. The cloud era for those was driven by &lt;em&gt;deployment&lt;/em&gt; convenience, not performance. A web tool runs in any browser; a desktop tool needs to be installed. That’s a real friction. But it’s a friction worth paying for the privacy it preserves.&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 crucially, &lt;strong&gt;RAR v5 extraction natively on Apple Silicon&lt;/strong&gt;, which has been a long-standing pain point for users who get RAR archives in 2026 (more often than you’d think — academic and design workflows still use it heavily).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every tool runs entirely on the Mac. No file leaves the device. No upload, no cloud round-trip, 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;The tools all support &lt;strong&gt;Shortcuts integration&lt;/strong&gt;, which means they can be composed into automated workflows. &lt;em&gt;“Compress all videos in this Downloads folder, output to ~/Compressed, delete originals over 100MB.”&lt;/em&gt; That’s a Shortcut, runs on a schedule, 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;MediaKit’s pricing was the most-debated decision internally before launch.&lt;/p&gt;

&lt;p&gt;The shape it shipped with: &lt;strong&gt;five tools free forever&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. Pro also includes a free 3-day trial of &lt;em&gt;all&lt;/em&gt; tools, so users can evaluate before deciding.&lt;/p&gt;

&lt;p&gt;The argument for the freemium structure was that the user should have a non-trivial path to actually using the app for free, not a teaser. Five tools is enough that a casual user could go years without paying, and that’s fine — the app’s job is to be useful first.&lt;/p&gt;

&lt;p&gt;The argument for putting the long tail behind Pro is that the long tail is what makes MediaKit valuable to the &lt;em&gt;power user&lt;/em&gt;, and the power user is who funds the development of the long tail. The two-tier structure aligns the studio’s incentives with the user’s: power users pay because they get disproportionate value; casual users pay nothing because they get the basic value for free.&lt;/p&gt;

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

&lt;p&gt;If you’re reading this and you have a habit of using online converters, &lt;a href=&quot;/apps/mediakit/&quot;&gt;MediaKit&lt;/a&gt; is the studio’s argument that the habit is unnecessary. The Mac in front of you can do the same processing locally, faster than you’d expect, without your files leaving the device.&lt;/p&gt;

&lt;p&gt;The free tier covers the common cases. The Pro unlock covers everything else, including the obscure cases (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 calmer way to do it.&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-25T00: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. Here 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 information, not a verdict. 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-25T00: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 are the highest-leverage assets in the indie marketing stack and most indie developers, including past versions of me, treat them as the worst chore of every release. Mockly is the studio&apos;s argument that the workflow should be a native Mac app, not a YAML-driven CI script.</summary>
    <content type="html">&lt;p&gt;App Store screenshots are the most underrated assets in the indie iOS marketing stack. They are the first thing a prospective user sees in a search result. They convert better than any description, any keyword, any rating. And most indie developers, in my own anecdotal sampling, treat them as the worst chore of every release.&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 argument that there is a better way, 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;The dominant solution for screenshot generation in the iOS indie world is &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. Combined with &lt;strong&gt;fastlane frameit&lt;/strong&gt; (which adds device frames) and &lt;strong&gt;fastlane deliver&lt;/strong&gt; (which uploads to App Store Connect), it constitutes a complete pipeline.&lt;/p&gt;

&lt;p&gt;I am not going to dunk on fastlane. It is genuinely useful, the team behind it has done a public service for indie developers for nearly a decade, and the tool is open source. If you have a deeply customised CI pipeline already and your screenshots fit within the templates fastlane provides, it is a reasonable choice.&lt;/p&gt;

&lt;p&gt;What it isn’t, structurally, is comfortable. 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;The friction is everywhere in this list and it compounds. The Swift UI tests rot. The YAML grows. The simulator silently changes its rendering between Xcode versions. The editorial work happens in a separate tool — Pixelmator, Photoshop, or hand-coded SwiftUI — which means the editorial assets and the automated assets diverge over time. 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;The core bet behind Mockly is that &lt;strong&gt;most indie screenshot needs are a GUI problem, not an automation problem&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A GUI tool gives you direct manipulation of the asset. You drag the screenshot from the simulator into the app. You pick a device frame from a library. You add text overlay, you compose multi-device layouts, you preview the final result instantly. The locale switcher swaps the underlying screenshot but keeps the layout. The 3D frames are rendered live, not as PNG overlays — meaning a four-degree rotation looks correct, with proper perspective and lighting, in a way 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 — but the &lt;em&gt;workflow&lt;/em&gt; is fundamentally different. Each screenshot becomes a small, owned asset that can be edited and re-exported as needed, instead of a regenerated artefact that is slightly different every time the simulator rolls.&lt;/p&gt;

&lt;p&gt;For studios that ship a polished, editorially-considered set of screenshots — the ones with multiple devices in one image, with overlay copy, with motion blur on transition shots — this is the workflow that fits.&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 at the screenshot composition time. Rotation, perspective, lighting, and reflections are real, not faked.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Localised composition.&lt;/strong&gt; A single layout, with text, multiple devices, and overlays, can be exported 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; No 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;It does not, deliberately, replace the automation pipeline. If your studio has a deep CI/CD investment and screenshots that need to regenerate from running tests on every release, fastlane stays in your stack. Mockly is for the editorial moment that lives upstream of the pipeline — the &lt;em&gt;deciding what the screenshot says&lt;/em&gt; part — and for the studios for whom that’s the bulk 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 decision here is the most aligned with 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, lifetime access, no subscription required.&lt;/p&gt;

&lt;p&gt;The specific addition for Mockly is &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. This was a deliberate choice — the alternative would have been per-seat pricing, which is the right call for SaaS but the wrong call for a tool that small studios use intermittently.&lt;/p&gt;

&lt;p&gt;The studio loses some revenue to Family Sharing. The studio gains, I think, the right shape of relationship with the user. A small indie tool should treat its small indie users as a household, not a contract.&lt;/p&gt;

&lt;h2 id=&quot;what-this-post-does-not-argue&quot;&gt;What this post does not argue&lt;/h2&gt;

&lt;p&gt;I’m not arguing every iOS developer should switch to Mockly. The largest, most automated indie pipelines are well-served by fastlane — and many of them have invested years in customisations that would be expensive to abandon.&lt;/p&gt;

&lt;p&gt;What I’m arguing is that a meaningful fraction 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, and that almost no one builds GUI tools for indie iOS workflows because the audience is “just” tens of thousands of developers globally.&lt;/p&gt;

&lt;p&gt;That audience is the audience this studio happens to be in. &lt;a href=&quot;/apps/mockly/&quot;&gt;Mockly&lt;/a&gt; is for them. $12.99, lifetime, Family Sharing supported. 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 what part of the chore is actually necessary.&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-25T00: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. The strength-training logger market is well-served. I shipped GymLogger X anyway, and the reason isn&apos;t features — it&apos;s that I wanted the wrist, not the phone screen, to be where a workout gets logged.</summary>
    <content type="html">&lt;p&gt;It’s the first weekend of March. The clocks shift forward in the US tomorrow night, which makes this — by quirk of biology rather than calendar — 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 in a moment.&lt;/p&gt;

&lt;p&gt;I want to use this weekend’s post to explain something specific: why this studio shipped a strength-training logger at all, when the category is one of the most well-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 against Strong (the long-running incumbent), Hevy (the rising design-led upstart), Fitbod (the AI-program one), Caliber (the coach-network one), and a long tail of niche loggers. All of them are good apps. The category is not under-served in the obvious sense.&lt;/p&gt;

&lt;p&gt;When I started building GymLogger X in late 2025, friends in the indie community asked me, gently, why. The honest answer was: not because of features. It was because of one specific thing the incumbents got 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, sometimes log a set if you tap through three menus.&lt;/p&gt;

&lt;p&gt;That is backwards for the actual gym experience. In the gym, your phone is in a bag or on a bench, somewhere not on your body. Your watch is on your body. The watch is the device that’s &lt;em&gt;with&lt;/em&gt; you between sets. The watch is where logging should happen.&lt;/p&gt;

&lt;p&gt;Building a logger around the wrist is technically harder than building a phone-first logger. The screen is small, the input vocabulary is constrained (Digital Crown, taps, voice), the latency budget for syncing back to the phone is tight, and Apple’s WatchKit constraints are real. The reason most apps don’t do it is that the engineering cost is significant and the user-base willing to &lt;em&gt;use&lt;/em&gt; it is narrower 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 happens on the wrist. Rest timers happen on the wrist. Live heart rate is glanceable on the wrist. The phone is for analytics, program editing, and history review — the things that benefit from a bigger screen.&lt;/p&gt;

&lt;p&gt;The user feedback has been clear: the people who want this &lt;em&gt;really&lt;/em&gt; want it. The people who don’t want this don’t notice it’s there. Both outcomes are fine.&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 piece of the bet is the analytics layer.&lt;/p&gt;

&lt;p&gt;Most strength loggers track sets and reps and stop there. The Pro tiers add some trend lines. None of them, in my experience, will quietly 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 does try 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 it when that number has stopped climbing while your training volume holds steady — 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;What it does &lt;em&gt;not&lt;/em&gt; do is automatically restructure your program for you, change your weights, or send you a coach’s nag. Those are real features in other apps. They are also things I think the user should choose to do, not the app’s place to impose. Plateau detection in GymLogger X is informational. The next move is yours, and 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 a freemium model that the studio has stuck to: core logging is free forever, Pro is $17.99/year, and there is a one-time &lt;strong&gt;$39.99 lifetime&lt;/strong&gt; 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 most often get asked about. The math on it is, candidly, not great for a studio chasing recurring revenue. A user who buys lifetime in year one and uses the app for seven years has paid the studio about a third of what an annual subscriber would have paid. The lifetime tier exists anyway because strength training is a long-term practice and a user’s training history should not be conditional on continuing a subscription.&lt;/p&gt;

&lt;p&gt;About 30% of GymLogger X paid users choose the lifetime tier. They are vocal, they are loyal, and they are the user-base I’m most personally proud 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 will not realise that 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% on the day after, raises perceived exertion noticeably, and depresses recovery markers (HRV, resting heart rate) for several days. In the gym, this presents as: a lift that felt easy last Tuesday feels heavy this Tuesday, and the user blames their effort rather than 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 you’ve been progressing well, this is the week the curve will flatten. &lt;strong&gt;It is not your training. It is the time change.&lt;/strong&gt; Take Tuesday’s session at last week’s weights instead of pushing for new ones. Resume normal progression next week. GymLogger X will not lecture you, but I will.&lt;/p&gt;

&lt;h2 id=&quot;the-plain-take&quot;&gt;The plain take&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 rather than the phone screen — and because nobody seemed to be building it. The lifetime price exists because strength training is a long game. The plateau detection exists because the data deserves an interpreter.&lt;/p&gt;

&lt;p&gt;For the polished iPhone-first design tier 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. They serve different lifters. Both are honest about what they’re for.&lt;/p&gt;

&lt;p&gt;Don’t lift heavy on Tuesday. Lift heavy next Tuesday.&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-02-28T00:00:00+00:00</updated>
    <author>
      <name>Lagerland Apps</name>
      <uri>https://lagerland-apps.github.io/lagerland-apps/</uri>
    </author>
    <summary type="html">The single hardest decision in Chessful&apos;s design wasn&apos;t the engine, the analysis, or the spaced-repetition trainer. It was that the app needed to feel like you were playing forty different people, not the same engine forty times wearing different 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 is the feature that quietly carries everything else. This is the post about 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. 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 isn’t a different opponent than Level 15. It’s the same opponent making mathematically random mistakes. After a dozen games you can feel the noise. The mistakes aren’t &lt;em&gt;wrong&lt;/em&gt; — they’re &lt;em&gt;uncorrelated with style&lt;/em&gt;. 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 are not noisy engines. 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. The app needs opponents that feel like &lt;em&gt;people&lt;/em&gt;.&lt;/p&gt;

&lt;h2 id=&quot;the-forty&quot;&gt;The forty&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 are designed to imitate any specific real grandmaster — that line is one 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 not glamorous. It is 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;What it produces is &lt;em&gt;recognisability&lt;/em&gt;. After ten games against the aggressive Sicilian player, you start to anticipate her openings. You start to know where her blind spots are. You start to play &lt;em&gt;against her&lt;/em&gt;, not against an abstract evaluation function. That recognisability is what makes the games feel like games, and it’s what makes improvement against Chessful’s opponents transfer to playing humans.&lt;/p&gt;

&lt;h2 id=&quot;the-post-game-thing&quot;&gt;The post-game thing&lt;/h2&gt;

&lt;p&gt;The other feature that took disproportionate effort is the post-game analysis, and it is genuinely 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 identifies the move that lost the game. It identifies the threat the user missed. It explains, in one or two sentences, what was happening structurally. Sometimes it suggests the principle the user should remember — &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). The combination produces something that reads like a chess teacher rather than a chess engine.&lt;/p&gt;

&lt;p&gt;This was disproportionately hard. It is also the thing users mention most.&lt;/p&gt;

&lt;h2 id=&quot;what-this-is-not&quot;&gt;What this is &lt;em&gt;not&lt;/em&gt;&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 what they do — competitive play with the world’s best chess infrastructure.&lt;/p&gt;

&lt;p&gt;What Chessful is for: the player who wants to improve quietly, against varied opponents, with explanations they can actually read, on a flight, in a kitchen, between meetings. No account required. No internet required. No ranking attached to your name that you’ll 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;That isn’t a marketing claim. It’s just 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. Free to try, premium for 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-25T00: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 is the most consequential web app most indie developers use, and it has been the same web app for ten years. AppMeta is the studio&apos;s quietest app and arguably the most useful — a native Mac client for the ASC API, built 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 single most consequential web app in the indie iOS developer’s day. It’s how 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;It is also, structurally, a web app from 2014 that has accreted features for a decade. It works. It is also, on a long-haul flight or in a tab adjacent to fifteen others, miserable.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/apps/appmeta/&quot;&gt;AppMeta&lt;/a&gt; is the native Mac client I built to 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;App Store Connect’s design constraints are not Apple’s fault, in fairness. They are managing 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 against that surface area is a hard problem, and the team that ships ASC ships a &lt;em&gt;lot&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;What ASC isn’t optimised for is the workflow of an indie developer with five-to-fifty apps shipping across twenty locales. Specifically:&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 rediscover the same keyword waste in every language because there’s no tool to surface it. (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;Every one of these is a real friction. None of them are catastrophic individually. Together they are why I had a recurring “App Store Connect” calendar block on my 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;The core of AppMeta is a Mac client that talks directly to the App Store Connect REST API and gives you a side-by-side view of your apps’ metadata. 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. The four things it changes:&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 collapses into ten minutes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Diff preview before push.&lt;/strong&gt; AppMeta shows you exactly what will change against the current live metadata before the push happens. This is the feature I trust more than I trust myself, because &lt;em&gt;it caught a typo in five different localisations on the day before I would have shipped them.&lt;/em&gt; Once that happens to you once, you do not 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 utilisation across every locale and surfaces wasted space, duplicates, and gaps. This used to be a spreadsheet I maintained by hand. It is now 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, a click away in the sidebar instead of behind ten slow page loads. Pick a review, type a response, send. The response goes through ASC’s regulated channels — Apple is the source of truth — but the workflow stays on the Mac.&lt;/p&gt;

&lt;p&gt;There’s also version submission, screenshot management, pricing changes, and a few smaller things. The point isn’t the feature checklist. The point 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;This is the question I get most about AppMeta, and I want to be plain about it.&lt;/p&gt;

&lt;p&gt;App Store Connect tooling is a developer tool. Developer tools have a long history of subscription-priced services — JetBrains, Sketch, Figma, Linear. The market would absolutely pay $19.99 a month for a good ASC client. I considered it.&lt;/p&gt;

&lt;p&gt;The reason I shipped AppMeta as a one-time $29.99 purchase is that subscriptions create a specific bad incentive for a tool like this: every month, you have to ship enough perceived value to justify the recurring charge. That pressure pushes the roadmap toward &lt;em&gt;more features&lt;/em&gt;, not toward the right features. AppMeta’s job is to be a fast, reliable native client. Adding features for the sake of a renewal cycle would compromise that.&lt;/p&gt;

&lt;p&gt;A one-time purchase forces a different discipline: ship a tool that’s worth $29.99 once, and let the work earn the next purchase from a new user, not extract a renewal from an existing one. The tradeoff is slower revenue. The advantage is honest design.&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-side companion.&lt;/p&gt;

&lt;p&gt;It is, specifically, the native client for the metadata-and-review portion of App Store Connect. The thing you spend an hour a day in during ship weeks. The thing that needed to stop being miserable.&lt;/p&gt;

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

&lt;p&gt;If you’re an indie iOS or macOS developer shipping in multiple locales and you’ve ever spent a Friday afternoon doing the locale-dropdown dance, &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 post 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-09T00: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 was built for that exact 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. Someone is doing math on a napkin.&lt;/p&gt;

&lt;p&gt;This is a small post about that exact 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;The default in most splitting tools is to divide the bill into equal shares. This works when the table ordered roughly the same things. It is unfair the moment the orders diverge.&lt;/p&gt;

&lt;p&gt;Equal-splitting punishes the lighter eater. The salad-and-wine person at our hypothetical table pays $78, when their actual order was closer to $32. They will not say anything because the maths is awkward and the social cost of asking exceeds the $46 in question. They will quietly resent it, the next dinner will feel slightly different, and over a year of small inequalities the friendship loses a little bit of trust without anyone being able to point at the moment it happened.&lt;/p&gt;

&lt;p&gt;The fix is item-level splitting. It takes thirty seconds with the right tool. 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;The dominant solution to this problem in the early 2020s was Splitwise. It works, with one structural friction: every participant has to have an account. The four friends at the table are now 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 valuable. For a one-off Valentine’s dinner with friends, it’s a tax on the relationship that nobody asked for.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/apps/rightsplit/&quot;&gt;RightSplit&lt;/a&gt; is built around the opposite premise: &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;The version that lives in my head when I think about RightSplit’s 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. Bottle of wine? Tap two people, and the app splits it 50/50. Round of beers shared by three? Same. Steak? Tap the person who ordered it.&lt;/li&gt;
  &lt;li&gt;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 produces four small messages — one per person — 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;Done. The app remembers the split for future reference if the owner cares to look.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That’s the whole product. There’s no shared account, no notification storm, no IOU ledger that follows you around for nine months. The group never has to install RightSplit. The friction lives entirely with the person who’s 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 interesting thing about this design is what happens when groups get bigger.&lt;/p&gt;

&lt;p&gt;For two people, item-level vs. equal split rarely matters. 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 equal-split, in the favour of whoever ordered modestly. That’s small, but it’s the kind of small that compounds across a year of group meals.&lt;/p&gt;

&lt;p&gt;For ten people — bachelor parties, family dinners, work outings — item-level vs. equal-split can be a $80-150 swing per person. At that point, equal-splitting isn’t just unfair; it’s the thing that turns 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. $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 scenarios.&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;There’s a category of software that exists specifically to remove a tiny amount of friction from human relationships, and I’d argue this category is undervalued. The financial impact of any individual split is small. The relational impact of &lt;em&gt;not&lt;/em&gt; having the awkward conversation about the bill is non-trivial. Friends remember small kindnesses; they remember small inequalities even more.&lt;/p&gt;

&lt;p&gt;If you went out to dinner tonight and someone is staring at a receipt right now, consider this the offhand suggestion that there’s a calmer way to handle the math.&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-25T00: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 wasn&apos;t withdrawal. It was rebuilding a habit of reading something, anything, in the small windows that used to be filled by scrolling. WanderWiki was, more than anything else, the tool I built 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 want to say it was clean and freeing, but the honest version is that 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;The hard part wasn’t withdrawal. The hard part was that there was nothing else trained to fit the same hole. The five-minute window between meetings, the queue at the coffee shop, the two minutes waiting for the tea kettle. These had been algorithmic-feed time for a decade. Without the feed, they were just silence — which is fine, except the brain that’s been on dopamine for ten years doesn’t know what to do with silence yet.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/apps/wanderwiki/&quot;&gt;WanderWiki&lt;/a&gt; is, more than anything else in this catalogue, the app I built 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. Specifically: didn’t try to be infinite.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The substrate was obvious. Wikipedia 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 make a calm reading habit out of Wikipedia, the problem wasn’t the substrate.&lt;/p&gt;

&lt;h2 id=&quot;for-you-without-surveillance&quot;&gt;“For You” without surveillance&lt;/h2&gt;

&lt;p&gt;The unsolved problem in non-feed reading apps is that 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 that profile to weight the recommendations. This works, and it’s also exactly the thing I deleted off my phone.&lt;/p&gt;

&lt;p&gt;The interesting question is whether you can have &lt;em&gt;For-You-style relevance&lt;/em&gt; without behavioural tracking. The WanderWiki answer is: yes, if you ask the user what they like instead of inferring it. The app has a one-screen onboarding where 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. This is &lt;em&gt;less personalised&lt;/em&gt; than a feed-based reader. It is also accountable to the user in a way the feed-based version cannot be — 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;This works for the same reason it has always worked in newspapers: time-anchored content gives the brain a small handhold. &lt;em&gt;Today&lt;/em&gt;, specifically. &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 a small thing, but it’s the feature I get the most direct user feedback on, and it’s why I kept it.&lt;/p&gt;

&lt;h2 id=&quot;offline-as-a-first-class-state&quot;&gt;Offline as a first-class state&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;This is the part that needs the most honesty. 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’s job is the small reading list you build while wandering, which is still there on a 13-hour flight, the moment the value of a feed-replacement is highest.&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 that doesn’t have a feed and doesn’t track behaviour is not going to outcompete Twitter for attention, and it shouldn’t try. WanderWiki sessions are short. Two articles, sometimes three. The session ends when the user is satisfied, not when the app runs out of things to show. This is intentional and it is the metric I most want to be lower than the competitors’ metric.&lt;/p&gt;

&lt;p&gt;Daily active users is a noisy number for an app like this anyway. The right number 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; That’s the bar.&lt;/p&gt;

&lt;h2 id=&quot;where-this-fits-in-a-privacy-first-catalogue&quot;&gt;Where this fits in a privacy-first catalogue&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/apps/wanderwiki/&quot;&gt;WanderWiki&lt;/a&gt; sits alongside a small handful of other apps in this catalogue that all share a posture: 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. 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-09T00: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 takes the other path on purpose.</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 is the post explaining 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’s happening underneath isn’t quite what most users think.&lt;/p&gt;

&lt;p&gt;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 credentials or — in newer arrangements — holds an OAuth token issued by your bank. Either way, the third party 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 isn’t shady. It’s the standard architecture of fintech, it’s regulated, and most of the time it works. But it has three properties worth being honest 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; Even 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! It is genuinely useful! It is also doing two specific things, and one of them is unrelated to the user’s stated goal.&lt;/p&gt;

&lt;p&gt;The first thing it does is identify recurring charges. Useful.&lt;/p&gt;

&lt;p&gt;The second thing it does is build a picture of &lt;em&gt;every other thing&lt;/em&gt; you spend money on, which is not what you signed up for and is the actual asset the company is building. The bill-tracking is a pretext for the data pipeline. Some of these companies are open about it (the ones whose business model is “find subscriptions you forgot about and offer to cancel them” — that’s the value exchange). Some are quieter.&lt;/p&gt;

&lt;p&gt;Either way, the user is paying with read access to their entire financial life for a feature that, in the end, is a list of things they could have written down 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; is built around the opposite 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. Widgets and Siri integration mean the daily friction is essentially zero — &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. There is no login, no email collection, no 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;This is, on paper, less convenient than a Plaid-connected app. In practice, the convenience gap is smaller than people expect. The first-time entry takes about fifteen minutes if you have a long list. After that, the friction is a notification you tap to mark a bill paid — same friction, 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;I want to be precise about the tradeoff, because hand-waving it is dishonest.&lt;/p&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.” This is a real value proposition, and AllPaid does not solve 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 honestly. The user just needs to walk in with their eyes open about what they are giving up.&lt;/p&gt;

&lt;p&gt;For everyone else — the user who knows roughly what they pay for, wants to be reminded to actually pay, wants to share rent with a roommate, wants a calendar view of the next thirty days, and does not want a third party reading their checking account in perpetuity — manual-first works.&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 I am aware the timing is not accidental. 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;The point of &lt;a href=&quot;/apps/allpaid/&quot;&gt;AllPaid&lt;/a&gt; is to be the calmer answer in that window. No bank login. No surveillance. No anxiety-driven onboarding. Just the boring, useful, local thing that helps you not miss a bill and not pay a late fee. Free, with Pro at $1.99 a month, $12.99 a year, or $24.99 lifetime — no subscription required.&lt;/p&gt;

&lt;p&gt;If this is the year you stop handing over read-access to your bank in exchange for features you could write yourself, this is the studio that thinks 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-25T00: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 life. 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. The app’s model of a human was that humans sleep at night. Her model of a human was that nurses sleep when the rotation lets them.&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 implicit model is a five-day workweek with weekends free, plus the assumption that “night” means a single uninterrupted block of darkness.&lt;/p&gt;

&lt;p&gt;Now imagine a typical nurse’s twelve-hour rotation: three days on, three days off, two-week cycle, with the days flipping to nights halfway through. Her sleep windows might be 10pm-6am one week, 9am-3pm the next, with a chaotic transition night in between. The sleep app’s model breaks. The recovery scores are nonsensical. The 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, 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 don’t serve any of them well.&lt;/p&gt;

&lt;h2 id=&quot;what-shift-aware-actually-means&quot;&gt;What “shift-aware” actually means&lt;/h2&gt;

&lt;p&gt;The first thing AfterShift does that generic apps don’t is take a different view of &lt;em&gt;what counts as a sleep session&lt;/em&gt;. It 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. 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;, which is 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, given the rotation pattern you’re on, given 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 against the average iPhone user’s resting heart rate. A 7-hour daytime sleep before a night shift can produce a higher Shift Recovery Score than an 8-hour night sleep before a day shift, because the former is set up to support the upcoming work block and the latter is misaligned. Generic sleep apps reverse that — daytime sleep gets penalised, night sleep rewarded — which is exactly backwards for this user.&lt;/p&gt;

&lt;h2 id=&quot;caffeine-timing-is-a-feature-not-a-footnote&quot;&gt;Caffeine timing is a feature, not a footnote&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 makes it into consumer apps.&lt;/p&gt;

&lt;p&gt;The simplified version: caffeine has a half-life of about five hours. Drinking it three hours before bed leaves enough in your system to disrupt sleep onset and architecture. Drinking it at the start of a night shift will keep you alert at the worst possible time — when you finally try to sleep at 9am. The right strategy depends on which way your shift is rotating, and most shift workers reverse-engineer it through years of trial and error.&lt;/p&gt;

&lt;p&gt;AfterShift bakes the strategy in. Tell the app your upcoming shift block, and it will tell you the latest sensible caffeine cutoff to protect your post-shift sleep. It’s not glamorous. It is, by user feedback, the single 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;The other thing I underestimated when I started was how much &lt;em&gt;administrative load&lt;/em&gt; shift workers carry around their own sleep. Knowing when you slept, knowing when your next shift starts, calculating recovery in your head, deciding whether you need a nap — all of this lives as background processing in their day, on top of the actual job.&lt;/p&gt;

&lt;p&gt;AfterShift takes that load. Calendar shift import handles the schedule input (most large employers publish rotations to a calendar feed nurses can subscribe to). The sleep windows are planned from the shift times, and actual sleep is read from Apple Health. The caffeine timing updates automatically when shifts change. The user doesn’t have to keep doing math.&lt;/p&gt;

&lt;p&gt;When the math goes away, the cognitive load goes down. When the cognitive load goes down, the actual sleep gets better. This is the second-order effect I didn’t predict.&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 generalist 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 studio’s better fit — it does interpretation across all your Apple Health data, with sleep as one of the categories. AfterShift narrows the lens specifically to people whose schedule is the problem.&lt;/p&gt;

&lt;p&gt;It is also not a clinical tool. Sleep disorders, narcolepsy, sleep apnoea — these need a sleep clinic, not an app. AfterShift’s Shift Recovery Score is informational; it is 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;the-point&quot;&gt;The point&lt;/h2&gt;

&lt;p&gt;There’s a category of human work that powers most of modern infrastructure — healthcare, transport, public safety, manufacturing — and the consumer software industry has mostly designed around them. Building &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, with the explicit assumption that their schedule isn’t a deviation from normal but the actual normal of millions of people.&lt;/p&gt;

&lt;p&gt;If you work nights, rotations, or anything that breaks the 9-to-5 mould, the app is on the App Store. And if you know a nurse, pilot, or paramedic who’s been quietly suffering 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-01-17T00: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 interpretation matters more than tracking.</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 don’t mean that in a glib way. I mean: I could open the Health app, watch a number go up and down, see a chart that resembled a small mountain range, and not be able to 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;That gap is what Observa was built to close.&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;Before anything else: Apple Health is excellent at the thing it’s built for. It collects, normalises, and persists health metrics with privacy guarantees no consumer system has ever offered. The charts are well-designed. The unit handling is meticulous. The data layer is honestly the best in the industry.&lt;/p&gt;

&lt;p&gt;What Apple Health &lt;em&gt;isn’t&lt;/em&gt; trying to do — and shouldn’t, in my view — is editorialise. It will not tell you that your HRV dropped because of last week’s two short nights. It will not connect your morning resting heart rate to the wine you drank on Saturday. It will not say, “your training load is twenty percent above your eight-week average and your recovery scores are dropping; consider a deload week.” Apple’s deliberate restraint here is correct. Health data is sensitive, and over-interpretation is a real danger.&lt;/p&gt;

&lt;p&gt;But for the user, that restraint leaves a gap. You have data. You don’t have meaning.&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 failure mode I’m describing. The brain is bad at pattern-matching across noisy time-series data. We see trends that aren’t there and miss trends that are. We anchor on the last measurement. We feel anxious about a single low reading and reassured by a single high one, neither of which means anything statistically.&lt;/p&gt;

&lt;p&gt;This isn’t a willpower problem. It’s a &lt;em&gt;display&lt;/em&gt; problem. A chart with seven hundred datapoints and no overlay is not a tool — it’s a Rorschach test.&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 explicitly:&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 day-of-week (don’t underestimate Sunday-night anxiety as a predictor).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;What does your HRV trend actually look like, normalised against your own baseline?&lt;/strong&gt; Not the population’s. Yours. A 38 ms HRV reading is meaningless without knowing whether your personal baseline is 32 or 56.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Which days in the last 90 had the largest deviation from baseline, and what else changed on those days?&lt;/strong&gt; This is where the interesting stories live. 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 consistent with your recovery, or is it diverging?&lt;/strong&gt; If both lines diverge, you are accumulating fatigue, regardless of how the individual workouts felt.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These aren’t medical diagnostics. They’re explicitly not. Observa cannot tell you whether you have a clinical sleep disorder, a cardiac issue, or an autoimmune condition. It will not pretend to. What it can do is take a year of your own data and turn it into three or four sentences a thoughtful coach might tell 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 that shaped Observa is the obvious one: health data should never leave your device.&lt;/p&gt;

&lt;p&gt;This sounds like a statement of values, and it is, but it’s also a technical decision with real product consequences. A cloud-based version of Observa would have access to better correlation models, larger datasets, and more compute. It would also be a target for breaches, a regulatory minefield in multiple jurisdictions, and — most importantly — a thing the user could not 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 tradeoff is that the analyses are simpler than what a cloud service could do. The advantage is that no one but you ever sees a single data point. There’s no cloud account to compromise. There’s no employee with database access. There’s no “we accidentally trained a model on your sleep data” press release in the future.&lt;/p&gt;

&lt;p&gt;I think that’s the right tradeoff for health data. I’m aware not everyone agrees, and there are use cases — clinical research, longitudinal population studies — where on-device cannot compete. Observa is not that product. It’s the &lt;em&gt;interpretation layer&lt;/em&gt; for one person’s own life, owned by them.&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’ve been opening the Health app, scrolling, and feeling vaguely unproductive about it, &lt;a href=&quot;/apps/observa/&quot;&gt;Observa&lt;/a&gt; is built for that exact moment. It reads what’s already in your Health database (with your permission, scoped to the categories you allow) and produces a calm weekly read instead of a panel of charts.&lt;/p&gt;

&lt;p&gt;It won’t tell you what to eat. It won’t tell you when to sleep. It will, occasionally, 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 let you decide what to do with that.&lt;/p&gt;

&lt;p&gt;That’s the whole product. Apple’s data layer plus a thin layer of honest interpretation. No tracking, no upload, no account, no medical advice — just the modest, useful thing that’s missing.&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-01-10T00: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. Here&apos;s the structural one: streak counters are a debt instrument. The app issues them; the user owes them; the app collects on the missed day. 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, the structural one — and it’s a particular 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. It feels like a reward.&lt;/p&gt;

&lt;p&gt;But the same counter has a second behaviour, and the second behaviour is the one that drives the engagement loop: it resets to zero on a miss. 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. It’s also what makes it a debt instrument disguised as a reward.&lt;/p&gt;

&lt;p&gt;When the app shows you a 143-day streak, it isn’t telling you “you’ve earned this.” It’s saying “if you don’t open me tomorrow, you owe me 143 days.” The number on screen is denominated in &lt;em&gt;future panic&lt;/em&gt;, not past achievement. Each additional day inflates the debt. The longer the streak, the more painful the reset, the more hostage-y the relationship.&lt;/p&gt;

&lt;p&gt;Apps know this. They build it deliberately. There’s a reason every meditation app, language app, and habit tracker shipped a streak counter the moment Snapchat showed it worked. It’s not that the designers think users want it. It’s that users &lt;em&gt;don’t&lt;/em&gt; want it, and the not-wanting is precisely what produces the open.&lt;/p&gt;

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

&lt;p&gt;There’s another quiet thing streaks do, and it 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. They mark a task complete that they didn’t actually do. They walk in circles in the kitchen to hit the daily steps. They train through an injury they should be resting.&lt;/p&gt;

&lt;p&gt;The metric &lt;em&gt;the app shows them as proof of progress&lt;/em&gt; causes them to do less of the actual progress. This is Goodhart’s Law in two-tap form. The streak ceases to measure 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 actively rewards your users for behaviour they will be ashamed of in a quiet moment, you are not building a tool. You are building a dependency.&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;, the question wasn’t “should we have a streak?” It was “what does the app show in the place where the streak would normally go?”&lt;/p&gt;

&lt;p&gt;The answer was: nothing.&lt;/p&gt;

&lt;p&gt;The home screen shows today’s plan and today only. Yesterday’s incomplete tasks aren’t red-marked or scolded. They’re offered as &lt;strong&gt;follow-ups&lt;/strong&gt; — a small affordance that says, in effect, “this is something you said you wanted to do; tap to bring it to today, or dismiss it.” The user retains agency. The app doesn’t editorialise about whether yesterday was a “good day” or a “bad day.”&lt;/p&gt;

&lt;p&gt;There’s a reflection view if you want to use it, and a focus-session timer if you want to use it, and neither of them 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;What this &lt;em&gt;gives up&lt;/em&gt; is a strong “open the app every single day or else” loop. Daily-active-user numbers are lower than they would be with a streak. I know this 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, instead, is what 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 is no flame. No “you broke your streak.” No catch-up modal. The plan is just there, and it’s today’s plan, and they can use it or not.&lt;/p&gt;

&lt;p&gt;Most users in that situation report something specific in feedback: relief. They expected to be punished — every other planner has trained them to expect it — and the absence of punishment makes them open the app the next day. It turns out &lt;em&gt;not being a guilt machine&lt;/em&gt; is itself a retention strategy, just a slower one.&lt;/p&gt;

&lt;p&gt;I don’t think Taskful Day will ever have the daily-active-user numbers of a streak-driven planner. That’s fine. The users it does keep are using it the way it’s meant to be used: as a tool that meets them where they are, 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, they’re punishing, they corrupt the metric they pretend to measure, and they teach users to lie to their tools. There is a small craft cost to refusing them and a real product cost to refusing them. 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, the answer is none of them — by design.&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-01-03T00: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 on 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 is the gentle, well-designed, beautifully-typeset push notification that you missed your goal — by &lt;em&gt;just a little&lt;/em&gt;, isn’t that a shame, but you can still recover if you log in &lt;em&gt;right now&lt;/em&gt;. Then a streak counter that resets if you don’t open the app for two days. Then a leaderboard against three friends you haven’t seen since college. Then a coach character with a frowning face. Then 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. They are designed by talented people, the typography is excellent, the animations are crisp, and they convert. They are doing exactly what their growth dashboards reward them for doing.&lt;/p&gt;

&lt;p&gt;What they are not doing is helping you train.&lt;/p&gt;

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

&lt;p&gt;If you’ve ever felt like a fitness app turned on you in week two, here 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 a thing more consistently.&lt;/li&gt;
  &lt;li&gt;The app instrumented “consistency” as 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;But streaks are mathematically brittle. Miss one day, the counter resets. The app’s growth team knows this — it’s why streaks work. The fragility &lt;em&gt;is&lt;/em&gt; the engagement loop.&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 get the bad-feeling spiral and quietly stop opening the app for the rest of the year.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Neither outcome is “you trained.” One is theatre. 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 respects you 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; Or, if there is one, it doesn’t reset to zero — it accumulates total days trained, lifetime, irreversibly. The progress is yours; you don’t lose it for missing Tuesday.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;A “follow-up” mechanic instead of a “miss” mechanic.&lt;/strong&gt; Tasks or workouts that didn’t happen yesterday are not punished or red-marked — they’re offered to you, gently, today. Roll forward, don’t reset.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Goals that don’t compare you to other people you didn’t choose to compare to.&lt;/strong&gt; No leaderboards by default. No friends whose routines you don’t actually want 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” is supportive. Same data, different relationship.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;A way to leave for a week without losing your data.&lt;/strong&gt; Vacations exist. Injuries exist. Lives happen. The app should still be there at the same level you left it.&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, no flame, no red X. Unfinished tasks roll forward to tomorrow. There is a focus-session timer if you want one and a reflective view if you want one, 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;I am not arguing every fitness app should be flat and joyless. There is real craft in pacing, in motivation, in the small celebration when you hit a personal record. I am arguing that the &lt;em&gt;baseline&lt;/em&gt; shouldn’t be a guilt machine. The celebration should be earned by the user’s actual achievement, not extracted by punishing the user’s actual 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 thing I can offer is this: &lt;strong&gt;pick the app that respects you in week three, not the one that converts hardest in week one&lt;/strong&gt;. The two are usually different apps, and the second category will hurt you in February.&lt;/p&gt;

&lt;p&gt;That’s the whole post. Go for a walk. Lift something. 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-25T00: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. Everywhere on the internet, people are listing what they will build, ship, optimize, and grow. Here&apos;s 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. The pleasant tradition of writing public roadmaps has already begun on every developer corner of the internet, and I’m sure most of them are sincere.&lt;/p&gt;

&lt;p&gt;I’d like to do the opposite. Here is 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. No analytics. No advertising networks. No “anonymized” telemetry that quietly fingerprints. That isn’t going to change in 2026, and it isn’t going to change because someone offers an attractive revenue share, either. The first time I add an ads SDK is the first time the studio’s whole positioning collapses.&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, twentieth. The studio is one person, and the surface area is already at the limit of what one person can support thoughtfully. If I ship a new app this year, it will be because the idea is good enough to displace something else — 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 be more “successful” by App Store metrics if I added streaks, daily notifications, badges, or social comparison. Taskful Day would convert harder if I shipped a streak counter. AfterShift would have a higher retention curve with a daily nag. I am 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;This is the one I expect the most disagreement on. I use language models in my own workflow. I think they’re useful. I will absolutely add genuine AI capability to apps where it earns a place — Observa’s plain-language interpretation of HRV is one example, Chessful’s mistake explanation is another. But “tap here to summarize your day with AI” buttons that don’t change anything are 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. I don’t need one. The studio is small, the apps are profitable, and adding investors to a one-person operation would mean adding 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;The other thing I’m not doing is disappearing. This journal is new, and I plan to write more honestly through 2026 than I have in any previous year — including when things go wrong, which they will. There will be shipping notes, rebrand stories, post-mortems on pricing experiments, and quiet essays about why a particular feature exists. None of it on a content-marketing schedule. All of it because there’s something worth saying.&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;For the apps you might already use, the practical answer to “what’s coming in 2026” is more of the same: better refinements, fewer additions, the same privacy posture, the same one-time-or-honest-freemium pricing. For new apps that ship this year, the bar will be high and the count will be low. Good.&lt;/p&gt;

&lt;p&gt;If that’s the kind of studio you want to use 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 — and I mean that — but it isn’t this one.&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 rather than 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>2025-12-27T00: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 about 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 14 iOS and macOS apps. Until now, the website has been app-page-first — you land on an app, you learn about it, you install it. That’s still the goal. But some stories are too broad for a single app page.&lt;/p&gt;

&lt;p&gt;This journal is for those stories.&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 are more than a App Store “What’s New” line. Design decisions, why a feature exists, why another one was cut. Not marketing — the actual reasoning.&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. When I have something worth saying rather than a point to prove.&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. Nothing social, no comments, no 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;That’s the whole thing. Welcome.&lt;/p&gt;
</content>
  </entry>

</feed>
