Preserve Companion identity during installation

This commit is contained in:
Franz Rolfsvaag 2026-07-22 21:03:17 +02:00
parent 88d9718b8d
commit 739e96eee6
4 changed files with 15 additions and 5 deletions

View File

@ -4,7 +4,7 @@ This directory is the single Lumi Companion product boundary. The current milest
Build prerequisites: the current .NET SDK with the .NET 8 targeting pack on Windows x64. The app targets .NET 8; .NET SDK 10 is recommended for Avalonia 12 source-generator compatibility. The native bridge additionally requires CMake, Visual Studio C++ tools, and the OBS 31+ SDK.
The app accepts a `.lumi-pairing.json` bootstrap package. A paired ZIP downloaded from Lumi contains the per-user Windows setup executable and one bootstrap file. Setup installs Companion under `%LocalAppData%\Programs\Lumi Companion`, imports the adjacent package, and launches the installed app. Companion exchanges the embedded token once, stores the returned device credential with Windows DPAPI, and removes the imported pairing file after success. Do not commit bootstrap packages, credentials, generated installers, build output, or logs.
The app accepts a `.lumi-pairing.json` bootstrap package. A paired ZIP downloaded from Lumi contains the per-user Windows setup executable and one bootstrap file. Setup installs Companion under `%LocalAppData%\Programs\Lumi Companion`, imports the adjacent package when this Windows user is not already paired, and launches the installed app. Existing portable installs retain the same current-user DPAPI credential instead of creating a duplicate device. Companion exchanges a newly imported token once and removes the pairing file after success. Do not commit bootstrap packages, credentials, generated installers, build output, or logs.
The companion never performs ASR in this MVP. Audio is normalized to 16 kHz mono signed 16-bit PCM, held in bounded memory, and sent to the paired Lumi host over TLS WebSockets. HTTP/WS works only for a package generated from the exact matching loopback Lumi origin. The OBS bridge talks only to the companion over a same-user named pipe.

View File

@ -52,6 +52,11 @@ var
SourcePath: String;
TargetPath: String;
begin
{ Portable and installed builds share the same DPAPI credential directory. Do
not create another authorized device merely because an existing user moves
the executable into its durable installed location. }
if FileExists(ExpandConstant('{localappdata}\Lumi\Companion\device.credential')) then
Exit;
if FindFirst(ExpandConstant('{src}\*.lumi-pairing.json'), FindRec) then
begin
try

View File

@ -104,6 +104,11 @@ public sealed class CompanionRuntime : IAsyncDisposable
SetState(WithBridgeState(State with { Detail = "Download a pairing package from Lumi, then open it here." }));
return;
}
// An installer migration preserves the current-user DPAPI credential. If a
// bootstrap was copied alongside it, it is unnecessary and should not remain
// on disk where a later local reset could accidentally consume it.
var redundantPairing = FindBundledPairingPackage();
if (redundantPairing is not null) try { File.Delete(redundantPairing); } catch { }
SetState(WithBridgeState(State with { Paired = true, DeviceName = Environment.MachineName, Host = credential.Host, Detail = "Connecting securely to Lumi…" }));
await ConnectAsync(credential);
}

View File

@ -10,8 +10,8 @@
"label": "Windows x64 per-user installer",
"filename": "Lumi.Companion-Setup.exe",
"url": "https://git.rolfsvaag.no/Rolfsvaag_Datateknikk/Lumi/releases/download/companion-v0.1.0-experimental.7/Lumi.Companion-Setup.exe",
"sha256": "df64ef4071edac02a5bce14ab067c68590fcc981922c498cb65bc18749cdd437",
"bytes": 32034028
"sha256": "a06319ecbda2369e0f756fb4429d95583a58a1c802ae3537cd44faf0032c3ded",
"bytes": 32037289
},
"artifacts": [
{
@ -21,8 +21,8 @@
"label": "Windows x64 self-contained",
"filename": "Lumi.Companion-win-x64.zip",
"url": "https://git.rolfsvaag.no/Rolfsvaag_Datateknikk/Lumi/releases/download/companion-v0.1.0-experimental.7/Lumi.Companion-win-x64.zip",
"sha256": "f5cbbe7fed80a216b3b8a2832000228c71fb117e757d2b3011eeba66c451403e",
"bytes": 41757364,
"sha256": "5578b61aafbcf40b84cfa846aa31f2e2ff49700f62692e00c8d0587eac0cb414",
"bytes": 41757402,
"entrypoint": "Lumi.Companion.App.exe"
}
]