The dev multi-instance use case (one instance screen-capturing the other for
marketing/training videos) exposed a real bug. BuildStartPath in
MainViewModel.Recording.cs builds the start name with no dedup:
var name = RecordingFile.BuildStartName(DateTime.Now) + ".mp4";
var path = Path.Combine(folder, name);
Only FinalizeRecordingAsync calls UniquePath. So two instances that start
recording in the same minute computed the identical path
(ty-20260927-1454-0000.mp4) and both ffmpeg processes wrote one file -- a
corrupt take, not an error message.
Creator's fix (2026-09-27): add a millisecond count to the filename timestamp.
New format is ty-<yyyyMMdd>-<HHmm>-<fff>-<hh2mm2>.mp4. Both the start name and
the final name derive from _recordStartTime, so the ffff segment survives the
rename-on-stop and the final name cannot collide with another same-minute take
either. No UniquePath call needed, which keeps the start path a pure function of
the timestamp and the existing collision suffix behaviour intact.
Tests: 2 new (the same-minute guard and the rename-survival guard), 5 existing
assertions updated for the format. RecordingSaveDialogTests' stem fixtures
updated to match. 369/369 pass, 0 warnings.
Note: the first test run reported 367/367 because only ytLive.csproj had been
built -- the stale test DLL never picked up the new tests. The real count is 369.
Encoder dual-output: StreamEnabled/RecordEnabled/RecordPath options; per-output
ffmpeg block (stream ->flv, record ->mp4); throw unless at least one output.
RecordingFile: auto-name ty-<yyyymmdd>-<start hhmm>-0000.mp4, rename-on-stop to
ty-...-<len hhmmss>.mp4 with numeric-suffix on collision. LayoutStore persists
record folder. MainViewModel: REC/ON-AIR pills, status light, single Start<->End
button (replaces Start/Stop variants), StopStream no longer signs out, explicit
session timer. About overlay widened. Sign In label + spacing before Start.
Tests: 244 passed / 246 (2 pre-existing: AudioPipeline gains-mute, RoundClip).
Build 0 warnings. Scope check clean.
Memory-map correction (derived-solution rule, 2026-08-29): image-shrink recipe was
never recorded when first done, so it was re-derived. Added Derived-solution/recipes
rule to AGENTS.md; MyMistakes.md now a permanent recipes registry (records the
verified WPF-imaging shrink recipe); schema.md rows MyMistakes as registry; ai.md
points to the rule. README hero image replaced: 3.2MB screenshot -> 1400x794 ->
188KB docs/ytLlive-preview.jpg (JPEG q82).