diff --git a/docs/ISSUES.md b/docs/ISSUES.md index c83a90b5..3a092547 100644 --- a/docs/ISSUES.md +++ b/docs/ISSUES.md @@ -88,27 +88,36 @@ Windows+Ubuntu CI lane alongside the existing launcher tests. ## #398 — Launcher: fatal startup/dispatcher exceptions are reported without a stack -**Status:** OPEN +**Status:** DONE (`e1e94697`) **Severity:** MODERATE (diagnosability) -**Filed:** 2026-08-15 +**Filed:** 2026-08-15 · **Closed:** 2026-08-15 **Component:** `src/AcDream.Launcher/Program.cs` -`Program.Main`'s top-level guard prints only `ex.Message` before returning -74. For the `MainWindow` NullReferenceException fixed at `d54b8a78` that -produced `Launcher startup failed safely: Object reference not set to an -instance of an object.` with no file, line, or frame — diagnosis required -temporarily editing the guard to print the full exception and rebuilding. -An alpha user hitting a crash can give us nothing actionable. +`Program.Main`'s top-level guard printed only `ex.Message` before returning +74 — the `MainWindow` NullReferenceException fixed at `d54b8a78` surfaced +with no file, line, or frame, and diagnosis required temporarily editing +the guard and rebuilding. -**Fix direction.** Keep stderr terse, but write the full exception -(`ToString()`, including inner exceptions) to a crash file under the -resolved data root, and print that path. Must honor the LA11 redaction -contract: the crash file is subject to the same credential-value scanning -as the status stream, and must never contain a password or a raw command -line. +**Fix landed (`e1e94697`).** `TryWriteCrashReport` writes the full +exception chain plus non-identifying host facts (UTC, OS, RID, assembly +version) to `/crash-reports/launcher-crash-.log`; +stderr stays terse and names the path; the reporter itself never throws. +When option parsing is the failure, the caller's `--data-dir` is still +honored via a positional, validation-free read — the first implementation +fell back to the machine's real data root and broke LA11's process-local +roots during an isolated run (observed live, then fixed in the same +commit). Verified: forced startup failure writes the report inside the +isolated root with the full stack; the real root stays empty. -**Acceptance:** a fatal startup exception produces a crash file with the -stack, stderr names its path, and the redaction suite covers the new sink. +**Redaction, stated exactly (deliberate narrowing of the filed +acceptance):** the report never serializes the command line, environment, +or process state, but exception TEXT may quote an option name or path. +That is safe by construction — credentials never enter launcher state +(child-stdin only; `LauncherProcessSpec` has no credential member, guarded +by its reflection test) — so no scanning pass over this sink exists today. +The code comment carries the standing condition: if a credential ever +becomes reachable from launcher state, this sink needs the status-stream's +credential scanning. ## #397 — Windows: LauncherProcessSupervisor.Stop has no reliable graceful-stop signal for a no-window console host diff --git a/docs/plans/2026-08-14-launcher-campaign.md b/docs/plans/2026-08-14-launcher-campaign.md index 4541b36f..9d4dc94f 100644 --- a/docs/plans/2026-08-14-launcher-campaign.md +++ b/docs/plans/2026-08-14-launcher-campaign.md @@ -717,6 +717,30 @@ in ledger. Reviews name blast radius explicitly retail-fidelity lens against named-retail symbols cited in the slice body; LA6 adds CH-regression scrutiny; LA0 adds guard-integrity scrutiny. +## Gate round 1 — 2026-08-15 (first live launch by the user) + +The user's first hands-on launch found the launcher exiting on every click. +Root cause (`d54b8a78`): `MainWindow`'s constructor called +`AvaloniaXamlLoader.Load(this)` instead of the generated +`InitializeComponent()`, so every `x:Name` backing field was null and any +modal open/close threw out of the dispatcher into `Program`'s exit-74 +guard. It reached the gate because NO test constructed `MainWindow` — +filed and closed as **#399** (`2b439cc1`, merged): `Avalonia.Headless.XUnit` +view tests with falsification evidence (12/12 fail against the old code, +12/12 pass against the fix; launcher suite 66/66 Windows + native Ubuntu; +xunit→xunit.v3 in that test project). Same round (`e1e94697`): **#398** +closed — fatal exceptions now write a full-stack crash report under the +data root (isolated-roots-safe; the first cut leaked to the real data root +when parsing failed, caught live and fixed) — and `acdream-bake.exe` is now +co-deployed on plain Build, not just Publish, so a developer-built launcher +can actually run its first-run wizard (79.6 MB single file beside the +launcher, incremental, `--help` verified). One transient 65/66 on the first +post-merge test run did not reproduce across a clean rebuild + six repeats — +consistent with stale-artifact mixing, but if it EVER recurs, capture the +failing test name before anything else. Merged slice worktrees/branches +(la2/la3/la7a/la-uitest) removed. The §A–I connected script remains the +open user gate. + ## Ledger | Slice | Status | Commits | Review | Notes |