0.1.0-alpha.2 bumped three version strings with a tool that writes UTF-8
WITH a BOM, and committed it. Neither build survives that:
package.json vitefu JSON.parses the raw string, so `npm run dev`
exited instantly — "Unable to read package.json"
tauri.conf.json the Tauri build script failed with "expected value at
line 1 column 1"; cargo exit 101
Cargo.toml tolerated, but wrong
`require()` hides this. Node strips a BOM on require and JSON.parse does
not, so reading package.json from a REPL reports a perfectly good file
while both builds refuse it. Only the raw bytes show it: EF BB BF.
All 191 tracked files scanned. These three were the only ones affected,
and they are exactly the three 5682dfc touched. Stripped with Node rather
than PowerShell, whose default Out-File/Set-Content encoding is what wrote
them in the first place — the files are byte-identical but for the three
leading bytes.
Cargo.lock carries the 0.1.0-alpha.1 -> alpha.2 propagation the release
commit left behind in the working tree.
The preview backend never received a volume — clips played at the crate
default (0.7) regardless of the slider, even muted. The session now sets
the preview volume from the app store (mute → 0) before the first load and
mirrors it live while the modal is open; the debug overlay's PREVIEW row
exposes the backend's resting volume as proof.
The player-bar volume (and fallback seek) fill is now always the accent
color — matching the waveform scrubber's played region — stepping up to
the hover shade on hover instead of white-until-hover.
Also syncs package-lock to the soulstream name + alpha version.
.gitignore now excludes everything that is not part of the app itself:
memory/, research/, TODO-Feature-Docs/, HANDOFF*/GAMEPLAN notes, .codex/,
.claude/ and logs. Version begins the alpha line at 0.1.0-alpha.1 across
the cargo workspace, package.json and tauri.conf.json.
src/lib/preview/ — framework-free ESM modules, per design §12–14:
- contracts.js: versioned manifest/item/source-ref factories; signed
URLs structurally excluded from manifests; Apple identity first-class.
- lease.js: discriminated MediaLease union; computeSafeForMs derives
lifetimes provider-clock-first with fallback/contradiction handling
(margins are ADRs backed by Phase 0 soak evidence).
- redact.js: URL redaction (host+hash+exp only) and the HTTPS + exact
host allowlist gate applied to initial URLs and every redirect.
- manifest.js: artist (rank order, exact-id dedupe), album (disc/track
sort, context inheritance) and fixture builders — pure, no fetching.
- session.js: reducer with session/generation guards on every async
action; keyed active item with derived playable indices/cursor;
auto-advance under fresh generations; close is terminal.
- resolver.js: PreviewResolver contract + scripted fixture resolver
with classified failures (stale_lease/not_found/network/…).
- transport.js: transport seam + deterministic fake (manual ticks).
- focus.js: revision gateway (all main-player entry points; focus-
internal tag) and the coordinator — acquisition only via a
generation-bound silence ack, restore only with revisions unchanged.
tests/preview/*.test.mjs run via `npm test` (node --test): 61 passing,
covering the full Phase 1 list in IMPLEMENTATION-PLAN §6 including the
exit gate: stale lease/play events are inert, no restoration after any
simulated main command, and no component renders anywhere.
The previous .git directory was found gutted (only info/ remained), so
history is unrecoverable locally. This commit restores version control
with the tree exactly as it stands: the working app, the preview-tracks
launcher on the artist hero, the scrollable-track-previews design bundle
(docs + approved mockups), and the Phase 0 validation artifacts.