release: the Plasma classroom becomes stable 0.2.0

0.1.50 was taken to the church and the things a container cannot answer
were answered on the hardware: boot, autologin, the panel after a reboot,
panel and browser scaling, Wonder Ink, Parent Call opening in the corner
and reaching the sanctuary with a typed name, readable and silent
notifications, HDMI audio and the volume keys.

The promotion is a fast-forward. The experiment was cut from the
published stable source and never diverged from it, so master reaches
this work without a merge and there is one history.

One thing changed for the release. The channel rules turn around:
classroom-v2 and hyprland are the obsolete channels now and a room on
either comes home to stable, while canary — where the next development
release goes — and any channel somebody named by hand stay where they
were put. A fresh installation has always defaulted to stable.

Nothing else moved. This is the 0.1.50 that was verified, with a version
number and a channel rule.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
ekklesia
2026-09-13 09:15:00 -05:00
co-authored by Claude Opus 5
parent ba8768cee5
commit 8db5e8dd9f
8 changed files with 82 additions and 34 deletions
+1 -1
View File
@@ -1 +1 @@
0.1.44 0.2.0
+34 -7
View File
@@ -1293,6 +1293,32 @@ survive that — and `lab reboot` is in every scenario. It re-fences now
and refuses to continue if either church network answers. The four and refuses to continue if either church network answers. The four
retained topics are the user's to clear; the commands are in the report. retained topics are the user's to clear; the commands are in the report.
## Stable: 0.2.0
The experiment is over. 0.1.50 was taken to the church and everything a
container could not answer was answered on the hardware: Plasma and KWin
boot, autologin works, the panel comes back after a reboot, the panel and
Chrome are the right size, Wonder Ink runs, Parent Call opens in the
corner, accepts a typed name and reaches the sanctuary, notifications are
readable and silent, HDMI audio and the volume keys work, and the room
looks the way it was meant to.
So the Plasma classroom is the stable line, and this branch's work is on
master. The promotion was a fast-forward: the experiment was cut from the
published stable source and never diverged from it, so there is one
history and no merge.
One thing changed for the promotion and nothing else did. The channel
rules turned around: `classroom-v2` and `hyprland` are the obsolete
channels now and a room on either comes home to `stable`, while `canary`
— the next development release's channel — and any channel named by hand
are left exactly where somebody put them. A fresh installation has always
defaulted to `stable` and still does.
Publishing followed the existing path: the package goes up through a
channel publish, and `update_stable.sh` moves the manifest afterwards,
manifest last.
## Unresolved risks ## Unresolved risks
In the order I would worry about them. In the order I would worry about them.
@@ -1362,13 +1388,14 @@ In the order I would worry about them.
machine's key, and the control computer cannot reach it either — so machine's key, and the control computer cannot reach it either — so
every result above is the lab's. The package is built and the deploy every result above is the lab's. The package is built and the deploy
commands are written down; the room itself is unverified. commands are written down; the room itself is unverified.
16. **The v2 channel still has no manifest.** `update_classroom_v2.sh` 16. **The experiment's channel is now the obsolete one.** It carried the
exists now and has not been run. Until it is, a v2 room takes no rooms while this was an experiment and 0.2.0 brings them home to
updates at all, and `classroom-migrate` moves every upgraded machine stable. It is kept, pointed at 0.2.0 so that a machine still on it
onto that channel — deliberately, because stable and canary would takes the release that moves it, and the 0.1.50 package stays hosted
both hand a Plasma room the sway build back. as the rollback.
17. **Nobody has typed into the anchored Parent Call card.** Layer shell 17. **Typing into the anchored Parent Call card was verified at the
gives it the keyboard — the entry takes focus and shows a caret — but church, not here.** Layer shell gives it the keyboard — the entry
takes focus and shows a caret — but
keyboard injection has never worked in this lab, so the first thing keyboard injection has never worked in this lab, so the first thing
to do on the bench is type a name into it. If it cannot be typed to do on the bench is type a name into it. If it cannot be typed
into, removing gtk-layer-shell from the package restores the centred into, removing gtk-layer-shell from the package restores the centred
+13 -7
View File
@@ -189,13 +189,19 @@ import re
import sys import sys
OBSOLETE_KEYS = ("COMPOSITOR", "HYPR_APPEARANCE") OBSOLETE_KEYS = ("COMPOSITOR", "HYPR_APPEARANCE")
# Every channel that serves a desktop this package replaces. A machine # Every channel that serves a desktop this package replaces.
# that has just installed the Plasma classroom must not be left pointed at #
# a line that will hand it the sway build back at the next release: stable # This list was the other way round while the Plasma desktop was an
# and canary both would. A room already on the v2 channel, or on one # experiment: rooms were moved off stable onto a channel of its own so
# somebody named deliberately, is left where it is. # that a sway release could not take them back. The Plasma classroom is
OBSOLETE_CHANNELS = {"stable", "canary", "hyprland"} # the stable one now, so the experiment's channel is the obsolete one and
CHANNEL = "classroom-v2" # rooms come home. hyprland never carried anything anybody runs.
#
# canary is deliberately not here. It is the next development release's
# channel, and a room an administrator put there is a room somebody meant
# to put there — as is one on a channel named by hand.
OBSOLETE_CHANNELS = {"classroom-v2", "hyprland"}
CHANNEL = "stable"
# The church broker. One address for every room. # The church broker. One address for every room.
BROKER_HOST = "10.40.0.2" BROKER_HOST = "10.40.0.2"
+7 -8
View File
@@ -107,8 +107,7 @@ check("the password is untouched",
check("and is never printed", "hunter2" not in output) check("and is never printed", "hunter2" not in output)
check("the compositor setting is gone", "COMPOSITOR" not in after) check("the compositor setting is gone", "COMPOSITOR" not in after)
check("and the appearance setting with it", "HYPR_APPEARANCE" not in after) check("and the appearance setting with it", "HYPR_APPEARANCE" not in after)
check("the channel moves off the experiment", check("the channel comes home to stable", "CHANNEL=stable" in after)
"CHANNEL=classroom-v2" in after)
check("the room's scale is preserved", "UI_SCALE=2.0" in after) check("the room's scale is preserved", "UI_SCALE=2.0" in after)
check("and everything else is left alone", check("and everything else is left alone",
"UPDATE_URL=https://updates.riverofglorymn.org" in after "UPDATE_URL=https://updates.riverofglorymn.org" in after
@@ -146,13 +145,13 @@ check("the settings are added", "MQTT_ENABLED=true" in after
and "MQTT_HOST=10.40.0.2" in after and "MQTT_PORT=1883" in after) and "MQTT_HOST=10.40.0.2" in after and "MQTT_PORT=1883" in after)
check("no credentials are invented", check("no credentials are invented",
"MQTT_USERNAME" not in after and "MQTT_PASSWORD" not in after) "MQTT_USERNAME" not in after and "MQTT_PASSWORD" not in after)
# stable and canary are both the sway line. A machine that has just taken # canary is where the next development release goes. A room somebody put
# the Plasma package and is left pointed at one of them is handed the old # there is a room somebody meant to put there.
# desktop back by the next release there: the upgrade undoing itself. check("canary is left where it is", "CHANNEL=canary" in after)
check("canary moves onto the v2 channel", "CHANNEL=classroom-v2" in after)
after, _ = migrate("CHANNEL=stable\nUI_SCALE=1.0\n") after, _ = migrate("CHANNEL=classroom-v2\nUI_SCALE=1.0\n")
check("and so does stable", "CHANNEL=classroom-v2" in after) check("and the experiment's own channel comes home",
"CHANNEL=stable" in after)
print() print()
print("4. running it twice changes nothing the second time") print("4. running it twice changes nothing the second time")
+4 -2
View File
@@ -215,8 +215,10 @@ check("Trixie validation runs before any upload", validation < first_rsync)
# upgraded room ends on the v2 channel with every setting this release # upgraded room ends on the v2 channel with every setting this release
# has, exactly once, and the command a technician runs is safe to run on # has, exactly once, and the command a technician runs is safe to run on
# a machine that is already converged. # a machine that is already converged.
check("the gate checks the upgraded channel", check("the gate checks a deliberate channel survives",
"'^CHANNEL=classroom-v2$'" in validation_script) "'^CHANNEL=canary$'" in validation_script)
check("and that the experiment's channel comes home",
"'^CHANNEL=stable$'" in validation_script)
check("and that every new setting arrived exactly once", check("and that every new setting arrived exactly once",
"for setting in LIVE_ENABLED AUDIO_OUTPUT UI_SCALE" in validation_script) "for setting in LIVE_ENABLED AUDIO_OUTPUT UI_SCALE" in validation_script)
check("and that running the migration by hand is safe", check("and that running the migration by hand is safe",
+3 -1
View File
@@ -26,7 +26,9 @@ with tempfile.TemporaryDirectory() as tmp:
for channel in ('stable', 'canary', 'hyprland', 'classroom-v2', 'custom'): for channel in ('stable', 'canary', 'hyprland', 'classroom-v2', 'custom'):
path.write_text(original.replace('CHANNEL=classroom-v2', 'CHANNEL='+channel)) path.write_text(original.replace('CHANNEL=classroom-v2', 'CHANNEL='+channel))
subprocess.run([sys.executable, '-c', code, str(path)], check=True, capture_output=True) subprocess.run([sys.executable, '-c', code, str(path)], check=True, capture_output=True)
expected = channel if channel in ('classroom-v2', 'custom') else 'classroom-v2' # The experiment's channel and hyprland come home to stable;
# everything anybody chose deliberately is left alone.
expected = 'stable' if channel in ('classroom-v2', 'hyprland') else channel
assert 'CHANNEL='+expected+'\n' in path.read_text() assert 'CHANNEL='+expected+'\n' in path.read_text()
assert 'MQTT_PASSWORD=literal $ and = characters\n' in path.read_text() assert 'MQTT_PASSWORD=literal $ and = characters\n' in path.read_text()
print('Display settings: scale bounds, config preservation, idempotence and channel migration passed.') print('Display settings: scale bounds, config preservation, idempotence and channel migration passed.')
+6 -2
View File
@@ -158,8 +158,12 @@ check(
'OBSOLETE_KEYS = ("COMPOSITOR", "HYPR_APPEARANCE")' in migrate, 'OBSOLETE_KEYS = ("COMPOSITOR", "HYPR_APPEARANCE")' in migrate,
) )
check( check(
"and comes off any channel that would undo the upgrade", "and comes off the channels that carried the experiment",
'OBSOLETE_CHANNELS = {"stable", "canary", "hyprland"}' in migrate, 'OBSOLETE_CHANNELS = {"classroom-v2", "hyprland"}' in migrate,
)
check(
"onto the stable line, which the Plasma classroom now is",
'CHANNEL = "stable"' in migrate,
) )
check( check(
"the rest of device.conf is rewritten line by line, not regenerated", "the rest of device.conf is rewritten line by line, not regenerated",
+14 -6
View File
@@ -147,11 +147,19 @@ if [[ -n "$previous" ]]; then
grep -q '^MQTT_PASSWORD=preserve-me$' /etc/ekklesia-classroom/device.conf grep -q '^MQTT_PASSWORD=preserve-me$' /etc/ekklesia-classroom/device.conf
grep -q '^CUSTOM_SETTING=preserve-me-too$' /etc/ekklesia-classroom/device.conf grep -q '^CUSTOM_SETTING=preserve-me-too$' /etc/ekklesia-classroom/device.conf
# And the one value the upgrade is supposed to change. canary is the # The channel a room was put on deliberately survives the upgrade.
# sway line: a room that has just taken the Plasma package and is left # canary is where the next development release goes, and the Plasma
# pointed at it is handed the old desktop back by the next release # classroom is the stable line now, so nothing here has to move.
# there, which is the upgrade undoing itself. grep -q '^CHANNEL=canary$' /etc/ekklesia-classroom/device.conf
grep -q '^CHANNEL=classroom-v2$' /etc/ekklesia-classroom/device.conf
# And a room that was carried through the experiment on its own
# channel comes home, because that channel is the obsolete one now.
sed -i 's/^CHANNEL=.*/CHANNEL=classroom-v2/' /etc/ekklesia-classroom/device.conf
classroom-migrate >/tmp/migrate-from-v2.log 2>&1
grep -q '^CHANNEL=stable$' /etc/ekklesia-classroom/device.conf
grep -q '^MQTT_PASSWORD=preserve-me$' /etc/ekklesia-classroom/device.conf
grep -q '^CUSTOM_SETTING=preserve-me-too$' /etc/ekklesia-classroom/device.conf
sed -i 's/^CHANNEL=.*/CHANNEL=canary/' /etc/ekklesia-classroom/device.conf
# Every setting this release has that the room predates, appended # Every setting this release has that the room predates, appended
# exactly once. classroom-migrate hands device.conf to the shared # exactly once. classroom-migrate hands device.conf to the shared
@@ -171,7 +179,7 @@ if [[ -n "$previous" ]]; then
done done
grep -q '^MQTT_PASSWORD=preserve-me$' /etc/ekklesia-classroom/device.conf grep -q '^MQTT_PASSWORD=preserve-me$' /etc/ekklesia-classroom/device.conf
grep -q '^CUSTOM_SETTING=preserve-me-too$' /etc/ekklesia-classroom/device.conf grep -q '^CUSTOM_SETTING=preserve-me-too$' /etc/ekklesia-classroom/device.conf
grep -q '^CHANNEL=classroom-v2$' /etc/ekklesia-classroom/device.conf grep -q '^CHANNEL=canary$' /etc/ekklesia-classroom/device.conf
# And by hand, on a machine that is already converged: the command a # And by hand, on a machine that is already converged: the command a
# technician runs must be safe to run twice. # technician runs must be safe to run twice.