Finish the wonderland: System told truthfully, in eight tabs instead of ten

Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
This commit is contained in:
Gabriel Brown
2026-08-24 23:31:52 -04:00
parent 9ffaf45a4d
commit be0e55214b
57 changed files with 5040 additions and 925 deletions
+132 -3
View File
@@ -52,11 +52,33 @@ tabless_ids="$(grep -oE '\{ page: "[a-z-]+", label: "[^"]*", icon: "[^"]*", tabs
tab_ids="$(grep -oE '\{ page: "[a-z-]+", label: "[^"]*" \}' "$routes" \
| sed -E 's/\{ page: "([a-z-]+)".*/\1/')"
# A third shape: a leaf that is reachable but is not a tab of anything. The
# manual is the only one -- it is reference material opened from About's Manual
# card and from deep links, not a control surface worth a permanent slot in the
# System strip. It still has to resolve, still has to have a SettingsShell case,
# and still has to be addressable by every caller holding its id, so it is a
# leaf for every purpose below except appearing in a tab strip.
hidden_block="$(sed -n '/property var hiddenLeaves:/,/\]/p' "$routes")"
hidden_ids="$(grep -oE 'page: "[a-z-]+"' <<<"$hidden_block" | sed -E 's/page: "([a-z-]+)"/\1/')"
[[ -n "$category_ids" ]] || fail 'no categories found in SettingsRoutes -- this contract is not reading it correctly'
[[ -n "$tab_ids" ]] || fail 'no tabs found in SettingsRoutes -- this contract is not reading it correctly'
[[ -n "$hidden_ids" ]] \
|| fail 'no hiddenLeaves found in SettingsRoutes -- the manual is a routable non-tab leaf and this contract is not reading the mechanism that makes it one'
# The leaves: every page a person can actually land on.
leaves="$(printf '%s\n%s\n' "$tabless_ids" "$tab_ids" | sed '/^$/d')"
leaves="$(printf '%s\n%s\n%s\n' "$tabless_ids" "$tab_ids" "$hidden_ids" | sed '/^$/d')"
# A hidden leaf that is also a tab, or also a tabless category, puts one page
# in two places -- and unlike the tab/category overlap below, nothing visible
# would show it, because the hidden half draws no row anywhere.
while read -r page; do
[[ -n "$page" ]] || continue
grep -qx "$page" <<<"$tab_ids" \
&& fail "\"$page\" is a hidden leaf and also a tab, so the same page id names two different places"
grep -qx "$page" <<<"$tabless_ids" \
&& fail "\"$page\" is a hidden leaf and also a category of its own"
done <<<"$hidden_ids"
# ── The taxonomy addresses each leaf exactly once ─────────────────────────────
# ShellState.settingsPage holds a leaf id, and the sidebar highlights the
@@ -103,6 +125,50 @@ while read -r pair; do
fi
done <<<"$retired_pairs"
# ── The System strip is eight tabs, and the two it lost are still reachable ──
#
# System had grown to ten tabs, which is more than a strip can show without
# becoming a second sidebar. Two left: Region & Language merged into Date &
# Time, because a date format and the clock that shows it are one subject, and
# the Manual became a hidden leaf.
#
# The count is pinned rather than derived because the number is the point: this
# is the horizontal space one row of tabs has. Anything that needs an eleventh
# subject needs a decision, not another entry.
python3 - "$routes" <<'PY' || fail 'the System category is not the approved eight-tab strip'
import re
import sys
expected = [
"about", "updates", "services", "storage",
"snapshots", "containers", "datetime", "sync",
]
text = open(sys.argv[1], encoding="utf-8").read()
block = re.search(r'\{ page: "system",.*?tabs: \[(.*?)\n \] \}', text, re.S)
if not block:
raise SystemExit("the System category could not be read")
found = re.findall(r'\{ page: "([a-z-]+)", label: "[^"]*" \}', block.group(1))
if found != expected:
raise SystemExit(f"System tabs are {found}, expected {expected}")
PY
# `region` retiring is only safe because every caller still holding it lands on
# the tab that absorbed it. The generic retired-map check above proves the
# target is a leaf; this proves it is the RIGHT leaf, which is the half a
# rename cannot get wrong quietly.
grep -qE '"region"[[:space:]]*:[[:space:]]*"datetime"' <<<"$retired_block" \
|| fail 'the retired "region" id does not resolve to "datetime", so every Vicinae command, deep link, and search result holding it lands on Home'
[[ ! -e "$settings_dir/RegionPage.qml" ]] \
|| fail 'RegionPage.qml still exists, so the retired route has a live page behind it after all'
# The manual is a leaf but not a tab. Said both ways: a strip entry would put
# reference material back in the System strip that the merge just freed, and
# losing the leaf would break About's Manual card and every deep link.
grep -qx 'manual' <<<"$hidden_ids" \
|| fail 'the manual is not a hidden leaf, so opening it from About or a deep link has no destination'
grep -qx 'manual' <<<"$tab_ids" \
&& fail 'the manual is a tab again, which is the System strip slot the consolidation just freed'
# ── Every leaf resolves everywhere ───────────────────────────────────────────
while read -r page; do
[[ -n "$page" ]] || continue
@@ -153,5 +219,68 @@ while read -r page_file; do
|| fail "$type_name.qml exists but nothing in SettingsShell instantiates it"
done < <(find "$settings_dir" -maxdepth 1 -name '*Page.qml')
printf 'settings nav contract: PASS (%d categories, %d leaves, %d retired ids)\n' \
"$(grep -c . <<<"$category_ids")" "$(grep -c . <<<"$leaves")" "$retired_count"
# ── The search index lands on leaves, not on ids that used to be leaves ──────
#
# SettingsSearch is the fifth place a page id is written down, and the only one
# where being wrong is silent: `resolve()` turns anything it does not recognise
# into Home, so a result whose page id was retired still opens a window, still
# looks like it worked, and lands somewhere else. That is exactly what the two
# Region & Language entries would have done -- and they are the entries most
# likely to be searched for by somebody who could not find the setting.
#
# Checked against the leaves this file already derived, so a page consolidated
# next time cannot leave a search result pointing at its old name.
search="$repo_dir/config/dot/quickshell/services/SettingsSearch.qml"
[[ -r "$search" ]] || fail "cannot read $search"
while read -r page; do
[[ -n "$page" ]] || continue
grep -qx "$page" <<<"$leaves" && continue
if grep -qE "\"[a-z-]+\"[[:space:]]*:[[:space:]]*\"$page\"" <<<"$retired_block"; then
fail "the search index routes to \"$page\", which is a retired id -- resolve() answers with its target, so the result lands somewhere the row never named"
fi
fail "the search index routes to \"$page\", which is not a leaf, so that result silently opens Home"
done < <({
grep -oE 'page: "[a-z-]+"' "$search"
sed -n '/property var groupPages:/,/})/p' "$search" | grep -oE ': "[a-z-]+"'
} | sed -E 's/.*"([a-z-]+)".*/\1/' | sort -u)
# The subjects the consolidation moved, each findable by its own name and each
# landing on the tab that now owns it. Region & Language merged into Date, Time
# & Region, so the words people arrive with for a format have to reach it; and
# About and Sync & Backup grew rows nobody could search for at all.
while IFS='|' read -r label page; do
[[ -n "$label" ]] || continue
python3 - "$search" "$label" "$page" <<'PY' \
|| fail "the search index does not offer \"$label\" on the $page page"
import re
import sys
text, label, page = open(sys.argv[1], encoding="utf-8").read(), sys.argv[2], sys.argv[3]
pattern = rf'\{{ label: "{re.escape(label)}",[^\n]*page: "([a-z-]+)" \}}'
match = re.search(pattern, text)
if not match:
raise SystemExit(f'no entry labelled "{label}"')
if match.group(1) != page:
raise SystemExit(f'"{label}" routes to {match.group(1)}, expected {page}')
PY
done <<'SEARCHABLE'
Hostname|about
Kernel version|about
Device model|about
Installed memory|about
Uptime|about
Serial number|about
Export settings|sync
Import settings|sync
Language|datetime
Regional formats|datetime
Currency|datetime
Measurement units|datetime
Paper size|datetime
First day of the week|datetime
Manual|manual
SEARCHABLE
printf 'settings nav contract: PASS (%d categories, %d leaves of which %d hidden, %d retired ids)\n' \
"$(grep -c . <<<"$category_ids")" "$(grep -c . <<<"$leaves")" \
"$(grep -c . <<<"$hidden_ids")" "$retired_count"