Splitting on separators anywhere in a line broke quoted strings apart, so
echo 'note; bun run changelog:check-prerelease-notes ...' produced a bare
command position and satisfied the ordering assertion.
Track quote state while scanning, stop at an unquoted inline comment, and
keep redirects from being read as pipes. Cover quoted separators, inline
comments, trailing comments, and pipe-vs-redirect.
An unanchored pattern matched the command text anywhere on an executable
line, so wrapping it in echo or printf satisfied the ordering assertion
while the workflow ran no validation at all.
Split each line on shell separators, strip control-flow prefixes, and
match anchored patterns against those command positions. Cover the helper
directly with cases for echo, printf, comments, and quoted mentions.
Matching a step's whole run body meant a commented-out command satisfied
the ordering assertion, so commenting out the prerelease notes check left
the test green while the workflow no longer validated anything.
Match executable lines only, and fold the version argument into the same
match so dropping it also fails.
The line-based guards allow-listed known-safe spellings, so bracket forms
like ${{ steps.version.outputs['VERSION'] }} never entered the candidate
list and passed, and the ordering check read indexOf over raw text, which
a comment naming the step could satisfy.
Parse the workflows instead and assert on step structure: no template
expression may appear in any run body, every step reading $RELEASE_VERSION
or $TAG_NAME must declare it in env, and the prerelease notes check must
precede the publishing step in the release job's step list.
Verified each guard fails on the three evasions it now covers.
The AUR test pinned the literal ${{ steps.version.outputs.VERSION }}
interpolation that moved into an env block, so it failed once the tag
value started reaching the shell as $RELEASE_VERSION.
Update that assertion and add guards for the invariant behind the move:
no tag-derived value may be interpolated into a run body, where GitHub
substitutes it before the shell parses the line. Also assert the
prerelease workflow runs the committed-notes check before it creates or
edits the release.
Document that the fragment delta resolves git paths against cwd, which
is both the project root and the repository root.
- Build the Swift window-tracking helper with an explicit `-target ...-apple-macos12.0` instead of letting swiftc stamp the build machine's OS, so the overlay attaches to mpv on older macOS (e.g. Ventura) instead of crashing at load
- Fold the standalone build-macos-helper.sh into prepare-build-assets.mjs and update docs/tests to match
- Only trim indentation before slicing ASS event fields so a trailing authored space at a fragment's end is kept, preventing words from being joined together when fragmented karaoke lines are reconstructed
- Add regression test covering event-boundary word spacing
- Reconstruct fragment-only karaoke while preserving canonical animated signs
- Reprocess live subtitles after initial playback and seek updates
- Add a development launcher for playable media files
- Stop deleting imm_daily_rollups/imm_monthly_rollups on unrelated schema version bumps; their source session/telemetry rows may already be pruned, so deleted buckets could not be rebuilt
- Run startup session-rollup maintenance before the lexical rollup backfill takes the write lock, so recovery no longer races playback writes
- Update the vocabulary summary totals changelog fragment to reflect that watch-time, activity, efficiency, and library charts are no longer cleared during rebuilds