Compare commits

..

No commits in common. "1dafc97d8ed30f6b13a178f7e66688179aeec455" and "32b95c02b8d56053cd49f23fbdd65886a84656d4" have entirely different histories.

11 changed files with 38 additions and 357 deletions

View file

@ -131,22 +131,21 @@ _validate_semver() {
case "$_v3" in '' | *[!0-9]*) _bad ;; esac case "$_v3" in '' | *[!0-9]*) _bad ;; esac
} }
# Walk backwards from HEAD until a non-auto-commit is found, return the # Walk backwards from HEAD until a non-auto-commit is found, return its
# resolved git ref (e.g. "HEAD~2"). Auto-commits are recognised by their # short SHA. Auto-commits are recognised by their canonical commit-
# canonical commit-message prefixes: # message prefixes:
# #
# - "chore(embedded): cut v<X.Y.Z>-beta" (beta auto-commit, build:993) # - "chore(embedded): cut v<X.Y.Z>-beta" (beta auto-commit, build:993)
# - "release: v<X.Y.Z> lockstep" (stable auto-commit, build:986) # - "release: v<X.Y.Z> lockstep" (stable auto-commit, build:986)
# #
# Used by the build-label helpers to derive a stable identifier (short # Used by compute_build_label to embed a stable source-SHA into beta
# SHA, three-word slug) from the underlying source state. The source # labels without triggering the embedded-commit recursion: HEAD shifts
# ref is invariant across the auto-commit step (HEAD shifts when # when embedded bytes change, but the source SHA returned here stays
# embedded bytes change), so a re-run on the same source state produces # the same as long as the underlying source hasn't moved.
# the same identifiers and no spurious commit.
# #
# Defensive cap: stops walking after 32 commits and returns whatever # Falls back to plain `HEAD` short SHA when the walk doesn't find a
# ref was reached. # non-auto-commit in the first 32 commits (defensive cap).
_source_commit_ref() { _source_commit_short_sha() {
_i=0 _i=0
_ref="HEAD" _ref="HEAD"
while [ "$_i" -lt 32 ]; do while [ "$_i" -lt 32 ]; do
@ -160,40 +159,7 @@ _source_commit_ref() {
esac esac
break break
done done
echo "$_ref" git -C "$root_dir" rev-parse --short=7 "$_ref" 2>/dev/null || echo "unknown"
}
# Three-word slug derived deterministically from the source commit's
# full SHA. Same source state → same slug; survives embedded auto-
# commits by deferring to _source_commit_ref.
#
# Three 4-hex-char chunks of the SHA are taken modulo the wordlist
# length (shared/build-words.txt). 283 words × 3 = 22M combinations,
# enough that a tester eyeballing two beta builds can tell at a glance
# whether they're running the same source.
#
# Format: "word-word-word" (lowercase, hyphen-separated).
_source_commit_slug() {
_ref=$(_source_commit_ref)
_full_sha=$(git -C "$root_dir" rev-parse "$_ref" 2>/dev/null || echo "0000000000000000")
_words_file="$root_dir/shared/build-words.txt"
if [ ! -f "$_words_file" ]; then
# Fall back to plain short SHA if the wordlist is missing
# (e.g. running from a checkout that predates this feature).
git -C "$root_dir" rev-parse --short=7 "$_ref" 2>/dev/null || echo "unknown"
return
fi
_wc=$(awk 'END{print NR}' "$_words_file")
_h1=$(echo "$_full_sha" | cut -c 1-4)
_h2=$(echo "$_full_sha" | cut -c 5-8)
_h3=$(echo "$_full_sha" | cut -c 9-12)
_n1=$(( (0x$_h1 % _wc) + 1 ))
_n2=$(( (0x$_h2 % _wc) + 1 ))
_n3=$(( (0x$_h3 % _wc) + 1 ))
_w1=$(awk -v n="$_n1" 'NR==n{print; exit}' "$_words_file")
_w2=$(awk -v n="$_n2" 'NR==n{print; exit}' "$_words_file")
_w3=$(awk -v n="$_n3" 'NR==n{print; exit}' "$_words_file")
echo "${_w1}-${_w2}-${_w3}"
} }
# Compute build label and channel. Reads positional args: # Compute build label and channel. Reads positional args:
@ -252,19 +218,17 @@ compute_build_label() {
alpha | beta) alpha | beta)
channel="$_arg" channel="$_arg"
_date=$(date -u +"%Y-%m-%d") _date=$(date -u +"%Y-%m-%d")
# Three-word slug derived from the *source* SHA — see # Resolve the *source* SHA — the most recent commit that is
# _source_commit_slug. Two builds carrying the same slug # not itself an embedded-files auto-commit. This stays stable
# were cut from the same source state, so a tester can # across the build's auto-commit step (build:971-995) which
# glance at the on-page label and confirm "yes, this is # advances HEAD by one when embedded bytes change. Using
# the cobalt-otter-meadow build I was emailed about" without # HEAD directly here would create an infinite loop: each cut
# having to look up a SHA. The slug is invariant across # would update the embedded label with the new chore-commit
# the embedded auto-commit step (build:971-995) so a re-cut # SHA, which would in turn require another chore commit.
# on unchanged source produces the same slug, no spurious # The source SHA is invariant across embedded auto-commits
# commit. Full source SHA is available via the binary's # so the second cut on the same source state is a no-op.
# `--version` output and the chart appVersion for any case _src_sha=$(_source_commit_short_sha)
# where exact provenance matters. build_label="v${_next_stable}-${channel} · ${_date} · g${_src_sha}"
_slug=$(_source_commit_slug)
build_label="v${_next_stable}-${channel} · ${_date} · ${_slug}"
_emit_build_label_sidecar "$_tool" _emit_build_label_sidecar "$_tool"
return 0 return 0
;; ;;

View file

@ -1,283 +0,0 @@
acorn
agate
alder
almond
amber
anchor
angle
antler
apple
apricot
arbor
arch
arrow
ashen
aspen
atlas
attic
auburn
aurora
azure
badge
bagel
ballad
balm
banner
barn
basil
basin
basket
beacon
beam
bear
beech
beetle
berry
biscuit
blanket
blossom
boat
bonnet
book
boulder
brass
bread
breeze
brick
bridge
brook
broom
bubble
bucket
buckle
button
cabin
cable
cactus
cake
candle
canvas
canyon
carpet
cart
cedar
chair
chalk
chamber
chapel
charm
cherry
chime
cinder
citrus
clay
cliff
cloud
clover
cluster
coal
coast
cobble
cocoa
coin
comet
compass
copper
cottage
cove
cradle
crane
crater
creek
crescent
cricket
crystal
daisy
dawn
deer
denim
diamond
ditch
dock
dolphin
dome
drift
drum
dune
dusk
eagle
ember
emerald
fable
falcon
feather
fence
fern
fiddle
finch
flag
flame
flask
flax
fleece
flint
flute
foam
forest
fork
fort
fountain
fox
garden
garnet
gear
ginger
glacier
glade
glass
globe
gold
granite
grass
grove
hammer
harbor
harp
harvest
hazel
hearth
heron
hill
hinge
hive
holly
hook
horizon
horn
hut
indigo
iris
iron
island
ivory
ivy
jade
jasper
juniper
kayak
kelp
kettle
key
kiln
kite
lake
lamp
lantern
lark
laurel
leaf
ledge
lemon
lens
lilac
lily
linen
locust
log
loom
lotus
maple
marble
marigold
marsh
mast
meadow
melon
mesa
meteor
mint
mirror
mist
mitten
moon
moor
moss
mug
nectar
nest
niche
nickel
nimbus
oak
oasis
ocean
onyx
opal
orbit
orchard
otter
owl
oyster
paddle
palm
panel
parrot
patio
pearl
pebble
pelican
pepper
perch
pier
pillow
pine
pipe
plank
plaza
pocket
pond
poplar
port
prairie
prism
puddle
quarry
quartz
quill
quilt
rabbit
raft
rain
ranch
raven
reed
reef
ribbon
ridge
river
robin
rock
rope
saddle
sage
sail
salt
sand
sapphire
sash
satin
scarf
sea
seal
seed
shawl
shield
shore
shrub
silver
silo
slope
smoke
snail
snow
spire

View file

@ -2131,7 +2131,7 @@ td[data-field="trackingNumber"] {
</svg> </svg>
<div class="header-title-group"> <div class="header-title-group">
<span class="app-header__title">ZDDC Archive</span> <span class="app-header__title">ZDDC Archive</span>
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-07 · g32b95c0</span></span> <span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-07</span></span>
</div> </div>
<button id="addDirectoryBtn" class="btn btn-primary">Add Local Directory</button> <button id="addDirectoryBtn" class="btn btn-primary">Add Local Directory</button>
<button id="refreshHeaderBtn" class="btn btn-secondary hidden" title="Refresh Data" style="font-size:1.1rem;"></button> <button id="refreshHeaderBtn" class="btn btn-secondary hidden" title="Refresh Data" style="font-size:1.1rem;"></button>

View file

@ -896,7 +896,7 @@ body {
</svg> </svg>
<div class="header-title-group"> <div class="header-title-group">
<span class="app-header__title">ZDDC Browse</span> <span class="app-header__title">ZDDC Browse</span>
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-07 · g32b95c0</span></span> <span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-07</span></span>
</div> </div>
<button id="addDirectoryBtn" class="btn btn-primary">Add Local Directory</button> <button id="addDirectoryBtn" class="btn btn-primary">Add Local Directory</button>
<button id="refreshHeaderBtn" class="btn btn-secondary hidden" title="Refresh listing" aria-label="Refresh listing" style="font-size:1.1rem;"></button> <button id="refreshHeaderBtn" class="btn btn-secondary hidden" title="Refresh listing" aria-label="Refresh listing" style="font-size:1.1rem;"></button>

View file

@ -1394,7 +1394,7 @@ body.help-open .app-header {
</svg> </svg>
<div class="header-title-group"> <div class="header-title-group">
<span class="app-header__title">ZDDC Classifier</span> <span class="app-header__title">ZDDC Classifier</span>
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-07 · g32b95c0</span></span> <span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-07</span></span>
</div> </div>
<button id="addDirectoryBtn" class="btn btn-primary">Add Local Directory</button> <button id="addDirectoryBtn" class="btn btn-primary">Add Local Directory</button>
<button id="refreshHeaderBtn" class="btn btn-secondary hidden" title="Refresh and rescan directory" aria-label="Refresh" style="font-size:1.1rem;"></button> <button id="refreshHeaderBtn" class="btn btn-secondary hidden" title="Refresh and rescan directory" aria-label="Refresh" style="font-size:1.1rem;"></button>

View file

@ -885,7 +885,7 @@ body {
</svg> </svg>
<div class="header-title-group"> <div class="header-title-group">
<span class="app-header__title">ZDDC</span> <span class="app-header__title">ZDDC</span>
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-07 · g32b95c0</span></span> <span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-07</span></span>
</div> </div>
</div> </div>
<div class="header-right"> <div class="header-right">

View file

@ -1792,7 +1792,7 @@ body.help-open .app-header {
</svg> </svg>
<div class="header-title-group"> <div class="header-title-group">
<span class="app-header__title">ZDDC Markdown</span> <span class="app-header__title">ZDDC Markdown</span>
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-07 · g32b95c0</span></span> <span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-07</span></span>
</div> </div>
<button id="addDirectoryBtn" class="btn btn-primary" title="Add a local directory">Add Local Directory</button> <button id="addDirectoryBtn" class="btn btn-primary" title="Add a local directory">Add Local Directory</button>
<button id="refreshHeaderBtn" class="btn btn-secondary hidden" title="Refresh directory" aria-label="Refresh" style="font-size:1.1rem;"></button> <button id="refreshHeaderBtn" class="btn btn-secondary hidden" title="Refresh directory" aria-label="Refresh" style="font-size:1.1rem;"></button>

View file

@ -2192,7 +2192,7 @@ dialog.modal--narrow {
</svg> </svg>
<div class="header-title-group"> <div class="header-title-group">
<span class="app-header__title">ZDDC Transmittal</span> <span class="app-header__title">ZDDC Transmittal</span>
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-07 · g32b95c0</span></span> <span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-07</span></span>
</div> </div>
<span id="no-js-notice" class="text-gray-400 text-xs italic">JavaScript not available</span> <span id="no-js-notice" class="text-gray-400 text-xs italic">JavaScript not available</span>
<!-- Publish split-button (Transmittal-specific primary action; <!-- Publish split-button (Transmittal-specific primary action;

View file

@ -1,9 +1,9 @@
# Generated by build.sh — do not edit. One <app>=<build label> per line. # Generated by build.sh — do not edit. One <app>=<build label> per line.
archive=v0.0.17-beta · 2026-05-07 · g32b95c0 archive=v0.0.17-beta · 2026-05-07
transmittal=v0.0.17-beta · 2026-05-07 · g32b95c0 transmittal=v0.0.17-beta · 2026-05-07
classifier=v0.0.17-beta · 2026-05-07 · g32b95c0 classifier=v0.0.17-beta · 2026-05-07
mdedit=v0.0.17-beta · 2026-05-07 · g32b95c0 mdedit=v0.0.17-beta · 2026-05-07
landing=v0.0.17-beta · 2026-05-07 · g32b95c0 landing=v0.0.17-beta · 2026-05-07
form=v0.0.17-beta · 2026-05-07 · g32b95c0 form=v0.0.17-beta · 2026-05-07
tables=v0.0.17-beta · 2026-05-07 · g32b95c0 tables=v0.0.17-beta · 2026-05-07
browse=v0.0.17-beta · 2026-05-07 · g32b95c0 browse=v0.0.17-beta · 2026-05-07

View file

@ -741,7 +741,7 @@ body.help-open .app-header {
</svg> </svg>
<div class="header-title-group"> <div class="header-title-group">
<span class="app-header__title" id="form-title">ZDDC Form</span> <span class="app-header__title" id="form-title">ZDDC Form</span>
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-07 · g32b95c0</span></span> <span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-07</span></span>
</div> </div>
</div> </div>
<div class="header-right"> <div class="header-right">

View file

@ -665,7 +665,7 @@ body.help-open .app-header {
</svg> </svg>
<div class="header-title-group"> <div class="header-title-group">
<span class="app-header__title" id="table-title">ZDDC Table</span> <span class="app-header__title" id="table-title">ZDDC Table</span>
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-07 · g32b95c0</span></span> <span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-07</span></span>
</div> </div>
</div> </div>
<div class="header-right"> <div class="header-right">