A devotional a day, and the fold hands back its language (v0.62.0) - #49
Merged
Conversation
- 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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
DEVOTIONALS. A bundled booklet of dated readings, one entry a day, starting
and stopping like a reading plan.
devotional-v1is the catalogue(
data/devotional.json, built by scripts/build-devotional.mjs fromdata-prep/devotional/);
plumbline-devotional-run-v1is the reader's ownfile 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()existsnext to
dayStamp()(midday UTC is the right cache key and the wrong answerto "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.devotionalSeededmakes 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
newBelieverflag, 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">saidvar(--popup), which isnot 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 rightcolour, which is how it survived.
Folding a foldable kept both panes and the pane's German.
maxPaneswas onlyenforced 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