Skip to content

A devotional a day, and the fold hands back its language (v0.62.0) - #49

Merged
glendonjklassen merged 3 commits into
mainfrom
devotionals
Aug 27, 2026
Merged

A devotional a day, and the fold hands back its language (v0.62.0)#49
glendonjklassen merged 3 commits into
mainfrom
devotionals

Conversation

@glendonjklassen

Copy link
Copy Markdown
Owner
  • DEVOTIONALS. A bundled booklet of dated readings, one entry a day, starting
    and stopping like a reading plan. devotional-v1 is the catalogue
    (data/devotional.json, built by scripts/build-devotional.mjs from
    data-prep/devotional/); plumbline-devotional-run-v1 is the reader's own
    file under home/devotionals/. Scripture is stored STRUCTURED, never as
    "John 3:16-21", so the passage renders from whichever corpus the reader is
    in and the label is written their way; text is keyed by language for the
    same reason the hymnal's is, so a translation is additive against a frozen
    format. Reading one is a full page with the passage set beneath the title,
    not a study-panel block.

    Pacing is sequence-anchored and DECLARED, not derived: a reading plan infers
    a finished day from the tracker, but nothing observable says a reflection was
    reflected on, so Done at the foot of the page is the only signal there is.
    Having banked a day, the next waits for the reader's next LOCAL midnight —
    the one place this model consults a calendar, and why localDay() exists
    next to dayStamp() (midday UTC is the right cache key and the wrong answer
    to "has a day passed?").

    The new-believer welcome starts the bundled booklet as it hands over — John 1
    still opens, with day 1's chip already on the strip. config.devotionalSeeded
    makes the boot RETRY safe: it tells "never managed to start it" (the pack's
    text stage had not landed) from "started it, and the reader stopped it",
    which is the meta:stockSeeded lesson. WHICH booklet comes off the catalogue's
    own newBeliever flag, never an id in a shell.

  • The .docx the church sent was being GZIPPED INTO THE WEB PACK and would have
    been served from the live site. .gitignore kept it out of git; it does not
    bind pack:data, which walks data/ on disk — and that walk was a denylist,
    so anything nobody thought to name shipped. It is an allowlist of shipping
    extensions now. Caught by app.spec.ts's prune check noticing the pin named it.

  • Settings' Sunday-service <input type="time"> said var(--popup), which is
    not a palette variable and never was — so it always took the light-cream
    FALLBACK: near-white ink on cream, invisible on EVERY dark theme, not only
    Nord where it was reported. Every other popup surface spells it
    --popupPaper; on a light theme the wrong name happened to land on the right
    colour, which is how it survived.

  • Folding a foldable kept both panes and the pane's German. maxPanes was only
    enforced where panes are created and restored, never when the width changed
    under a running app — and the chip that sets a pane's language lives on the
    pane strip, which Shell hides under 700px, so the override had no control
    left to undo it ("basically stuck on German"). Folding now collapses to the
    ACTIVE pane and hands it back to the app language.

  • Copy: "Follow the device" -> "System theme" / "System language"; "How should
    the words read?" -> "Choose text style:"; "Count your times through the
    Bible" -> "Track how many times you have read the Bible"; "Tag to gather
    into" -> "Tag to add verses to". The new-believer welcome loses its "start
    reading" and "memorize" beats to a devotional beat that says one has been
    started for them — the four retired ids stay DEFINED because Android's
    FirstRun.kt still references them and check-i18n scans Kotlin.

  • The Last opened bookmark chip is stood down: the app already reopens where
    the reader left off, so it named the place they were standing and changed
    every time they turned a page. One commented-out line to bring back.

  • thread-editing's drag-reorder e2e is deleted (maintainer's call). It drove
    the grip with raw pointer events and failed on CI without the feature ever
    failing; the reorder write behind it is the one the up/down links make, and
    those still have coverage.

🤖 Generated with Claude Code

- DEVOTIONALS. A bundled booklet of dated readings, one entry a day, starting
  and stopping like a reading plan. `devotional-v1` is the catalogue
  (`data/devotional.json`, built by scripts/build-devotional.mjs from
  data-prep/devotional/); `plumbline-devotional-run-v1` is the reader's own
  file under `home/devotionals/`. Scripture is stored STRUCTURED, never as
  "John 3:16-21", so the passage renders from whichever corpus the reader is
  in and the label is written their way; text is keyed by language for the
  same reason the hymnal's is, so a translation is additive against a frozen
  format. Reading one is a full page with the passage set beneath the title,
  not a study-panel block.

  Pacing is sequence-anchored and DECLARED, not derived: a reading plan infers
  a finished day from the tracker, but nothing observable says a reflection was
  reflected on, so Done at the foot of the page is the only signal there is.
  Having banked a day, the next waits for the reader's next LOCAL midnight —
  the one place this model consults a calendar, and why `localDay()` exists
  next to `dayStamp()` (midday UTC is the right cache key and the wrong answer
  to "has a day passed?").

  The new-believer welcome starts the bundled booklet as it hands over — John 1
  still opens, with day 1's chip already on the strip. `config.devotionalSeeded`
  makes the boot RETRY safe: it tells "never managed to start it" (the pack's
  text stage had not landed) from "started it, and the reader stopped it",
  which is the meta:stockSeeded lesson. WHICH booklet comes off the catalogue's
  own `newBeliever` flag, never an id in a shell.

- The .docx the church sent was being GZIPPED INTO THE WEB PACK and would have
  been served from the live site. .gitignore kept it out of git; it does not
  bind `pack:data`, which walks data/ on disk — and that walk was a denylist,
  so anything nobody thought to name shipped. It is an allowlist of shipping
  extensions now. Caught by app.spec.ts's prune check noticing the pin named it.

- Settings' Sunday-service `<input type="time">` said `var(--popup)`, which is
  not a palette variable and never was — so it always took the light-cream
  FALLBACK: near-white ink on cream, invisible on EVERY dark theme, not only
  Nord where it was reported. Every other popup surface spells it
  `--popupPaper`; on a light theme the wrong name happened to land on the right
  colour, which is how it survived.

- Folding a foldable kept both panes and the pane's German. `maxPanes` was only
  enforced where panes are created and restored, never when the width changed
  under a running app — and the chip that sets a pane's language lives on the
  pane strip, which Shell hides under 700px, so the override had no control
  left to undo it ("basically stuck on German"). Folding now collapses to the
  ACTIVE pane and hands it back to the app language.

- Copy: "Follow the device" -> "System theme" / "System language"; "How should
  the words read?" -> "Choose text style:"; "Count your times through the
  Bible" -> "Track how many times you have read the Bible"; "Tag to gather
  into" -> "Tag to add verses to". The new-believer welcome loses its "start
  reading" and "memorize" beats to a devotional beat that says one has been
  started for them — the four retired ids stay DEFINED because Android's
  FirstRun.kt still references them and check-i18n scans Kotlin.

- The Last opened bookmark chip is stood down: the app already reopens where
  the reader left off, so it named the place they were standing and changed
  every time they turned a page. One commented-out line to bring back.

- thread-editing's drag-reorder e2e is deleted (maintainer's call). It drove
  the grip with raw pointer events and failed on CI without the feature ever
  failing; the reorder write behind it is the one the up/down links make, and
  those still have coverage.
The reader had already given their service time in Settings, and Share asked
them to type it AGAIN into a free "when and where" line — which the link then
carried as somebody's prose, unformattable, unlocalizable, and uncheckable.

`Church.info` is gone. In its place `Church.service` is MINUTES SINCE LOCAL
MIDNIGHT, the same grain as `config.sunday_service` — and for the reader's own
church it IS that field: there is one stored number, the one Settings and the
Share pane both edit and the Sunday bookmark already reads. `session.church`
reads it back on the way out, `setChurch` writes it there rather than keeping a
second copy, and a church arriving from someone else's link carries its own
(which is why the struct has the field at all).

On the wire it travels as `churchService=600`, so the recipient's app writes
the time THEIR way instead of reading someone else's formatting: English gets
"Meets Sundays at 10:00 AM", German "Trifft sich sonntags um 10:00". The clock
is core::church::clock (12-hour for English, 24-hour otherwise); the words come
from the catalogue, so the line is not a sentence built in code.

- The Share pane grows the service-time control, bound to the same
  `config.sundayService` Settings edits — one value, two places to set it.
- Adopting a shared church now goes through `setChurch` rather than assigning
  `config.church`: assigning dropped the time on the floor, so a link that said
  when the church meets left the reader with no time at all.
- `church_vectors.json` carries the new field, including a row that exercises a
  set time and one where a minute outside a day reads as "never said" — the
  table is the parity contract and both sides read it.
- The link format changed without a migration, deliberately: pre-release, and
  the maintainer's call. An old link's `churchInfo` is simply ignored.
- `settings.churchInfo` stays DEFINED because Android's ShareScreen.kt and
  FirstRun.kt still reference it and check-i18n scans Kotlin.
Whitespace only: rustfmt's own line-joining on three blocks the new devotional
and church code added. The lint job runs `cargo fmt --all --check`, which I had
not run locally before pushing.
@glendonjklassen
glendonjklassen enabled auto-merge (squash) August 27, 2026 04:49
@glendonjklassen
glendonjklassen merged commit 3bf3f14 into main Aug 27, 2026
8 checks passed
@glendonjklassen
glendonjklassen deleted the devotionals branch August 27, 2026 04:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant