Compare commits

...
Author SHA1 Message Date
Meta Vens
d7e39fe495 Wire EVE native program output contract 2026-05-25 18:01:29 +01:00
9 changed files with 232 additions and 2 deletions

View file

@ -0,0 +1,59 @@
# EVE Program Output
## Authority Map
- Owner: Fensalir owns the visible D3D12 program pixels.
- Inputs: Fensalir reads the current `AquariumFrame`, render plan, GPU resources,
and overlay state.
- Outputs: a named shared D3D12 `B8G8R8A8_UNorm` texture containing the completed
backbuffer for the current frame.
- Derived state: Mimir publication profiles describe the stream contract; they
do not render pixels. EVE receives decoded pixels and composites them.
- Forbidden writers: WebKit, DOM layout, browser dashboards, OBS capture, and
desktop/window capture do not own this path.
- Shared paths: local display and EVE streaming both use the same completed
Fensalir backbuffer copy.
- Deletion line: diagnostic Sunshine/Moonlight or desktop-duplication probes may
prove network/decode budget, but they are not production authority.
## Current Mechanism
Set these before launching the Mimir app:
```powershell
$env:FENSALIR_PROGRAM_OUTPUT_D3D12 = "1"
$env:FENSALIR_PROGRAM_OUTPUT_NAME = "Global\MimirFensalirProgramTexture"
dotnet run --project .\src\Mimir.App\Mimir.App.csproj
```
Fensalir creates a shareable D3D12 texture with that name and copies the finished
backbuffer into it during the present pass. A hardware encoder process should
open that named texture, encode H.264/HEVC with GPU hardware, and send frames to
EVE's native receiver.
`scripts/start-eve-program-output.ps1` starts the Mimir/Fensalir app with the
shared-texture output enabled and verifies the `eve` SSH target before launch.
## Receiver Contract
EVE owns:
- network receive;
- hardware decode;
- texture upload/import;
- final fullscreen composite;
- touch/Pencil/sensor uplink later.
EVE does not own:
- dashboard DOM;
- Chromium/WebKit compatibility;
- layout parity;
- Mimir timing authority;
- OBS composition authority.
## Smoke
```powershell
dotnet run --project .\src\Mimir.BufferSmoke\Mimir.BufferSmoke.csproj -- --eve-program-output-contract-smoke
```

View file

@ -28,6 +28,11 @@ a named invariant that the native runtime cannot protect yet.
- Mimir public identity, branding, and Face memory.
- `Mimir.slnx` with `src/Mimir.App` and `src/Mimir.Runtime`.
- Fensalir host bootstrapping from `Mimir.App`.
- [[eve-program-output|EVE Program Output]] now owns the first native EVE
streaming contract: Fensalir can publish the completed D3D12 backbuffer into a
named shared texture when `FENSALIR_PROGRAM_OUTPUT_D3D12=1`, and Mimir records
the EVE-facing publication profile as a native D3D12 stream rather than a
WebKit/dashboard path.
- `MimirSynchronizationHub`, `MimirRollingStreamBuffer`, stream descriptors, and
`IMimirStreamSource`.
- Configurable five-second default rolling buffers for local and network audio

View file

@ -26,6 +26,7 @@ flowchart TD
N --> E["Fensalir GPU fusion + UI"]
N --> F["Faust/native DSP"]
E --> G["Spout2/program video"]
E --> V["EVE native shared-texture stream"]
F --> H["program stems + spatial bed"]
G --> I["OBS"]
H --> I
@ -42,10 +43,13 @@ Ownership:
- `Mimir.Runtime` owns app-level stream buffers and synchronization.
- Native capture workers own device reads.
- Fensalir owns dense visual fusion, material/brush/splat reconciliation,
D3D12 interop, runtime UI, and Spout2 publication.
D3D12 interop, runtime UI, Spout2 publication, and the completed backbuffer
texture copied into the EVE shared D3D12 program-output surface.
- Faust/native DSP owns hot audio alignment, suppression, separation,
spatialization, and stem generation.
- OBS owns broadcast controls.
- EVE owns native decode/composite for its fullscreen display path; it does not
own layout, WebKit compatibility, or timing authority.
Invariant: the live window is bounded, in memory, and has one timing authority.
No private history outlives the rolling buffer.

View file

@ -0,0 +1,47 @@
param(
[string] $Target = "eve",
[string] $SharedTextureName = "Global\MimirFensalirProgramTexture",
[string] $Configuration = "Debug",
[string] $LogPath = "logs\eve-program-output-fensalir.log",
[string[]] $AppArguments = @()
)
$ErrorActionPreference = "Stop"
$repoRoot = Split-Path -Parent $PSScriptRoot
$absoluteLogPath = Join-Path $repoRoot $LogPath
$absoluteErrorLogPath = [System.IO.Path]::ChangeExtension($absoluteLogPath, ".err.log")
$logDirectory = Split-Path -Parent $absoluteLogPath
if (-not (Test-Path $logDirectory)) {
New-Item -ItemType Directory -Path $logDirectory | Out-Null
}
Write-Host "Checking EVE SSH target: $Target"
ssh $Target "uname -a >/tmp/mimir-eve-program-output-check.txt && cat /tmp/mimir-eve-program-output-check.txt"
$env:FENSALIR_PROGRAM_OUTPUT_D3D12 = "1"
$env:FENSALIR_PROGRAM_OUTPUT_NAME = $SharedTextureName
$projectPath = Join-Path $repoRoot "src\Mimir.App\Mimir.App.csproj"
$dotnetArgs = @(
"run",
"--project",
$projectPath,
"-c",
$Configuration,
"--"
) + $AppArguments
Write-Host "Starting Mimir/Fensalir with shared D3D12 output: $SharedTextureName"
Write-Host "Log: $absoluteLogPath"
$process = Start-Process -FilePath "dotnet" `
-ArgumentList $dotnetArgs `
-WorkingDirectory $repoRoot `
-RedirectStandardOutput $absoluteLogPath `
-RedirectStandardError $absoluteErrorLogPath `
-WindowStyle Hidden `
-PassThru
Write-Host "Started PID $($process.Id). Poll with:"
Write-Host " Get-Content -Tail 40 '$absoluteLogPath'"
Write-Host " Get-Content -Tail 40 '$absoluteErrorLogPath'"

View file

@ -84,6 +84,11 @@ if (args.Any(arg => string.Equals(arg, "--perfect-machine-profile-smoke", String
return RunPerfectMachineProfileSmoke();
}
if (args.Any(arg => string.Equals(arg, "--eve-program-output-contract-smoke", StringComparison.OrdinalIgnoreCase)))
{
return RunEveProgramOutputContractSmoke();
}
if (args.Any(arg => string.Equals(arg, "--perfect-machine-contract-smoke", StringComparison.OrdinalIgnoreCase)))
{
return await RunPerfectMachineContractSmokeAsync(
@ -423,6 +428,32 @@ static int RunChirpletSelfTest()
return 0;
}
static int RunEveProgramOutputContractSmoke()
{
var output = MimirEveProgramOutputConfigurations.NativeSharedTexture;
var publication = MimirObsPublicationConfigurations.EveNativeProgram;
Console.WriteLine(
$"eve-output id={output.Id} host={output.TargetHost} port={output.TargetPort} texture=\"{output.SharedTextureName}\" {output.TargetWidth}x{output.TargetHeight}@{output.TargetFramesPerSecond} transport={output.Transport} webkit={output.UsesWebKit} diagnostic={output.DiagnosticOnly}");
Console.WriteLine(
$"eve-publication id={publication.Id} videoKind={publication.VideoKind} source=\"{publication.VideoSourceName}\" diagnostic={publication.DiagnosticOnly}");
foreach (var requirement in output.RequiredEnvironment)
{
Console.WriteLine($"eve-env {requirement}");
}
if (output.UsesWebKit ||
output.DiagnosticOnly ||
output.Transport != MimirEveProgramOutputTransport.D3D12SharedTextureHardwareEncode ||
publication.VideoKind != MimirObsVideoPublicationKind.EveNativeD3D12Stream ||
!string.Equals(output.SharedTextureName, publication.VideoSourceName, StringComparison.Ordinal))
{
Console.Error.WriteLine("EVE program output contract is split-brained.");
return 1;
}
return 0;
}
static int RunChirpBinSelfTest()
{
var timeline = MimirChirpBinTimeline.Default;

View file

@ -0,0 +1,64 @@
namespace Mimir.Runtime.Synchronization;
public enum MimirEveProgramOutputTransport
{
D3D12SharedTextureHardwareEncode,
SunshineMoonlightProbe,
DesktopDuplicationDiagnostic
}
public sealed record MimirEveProgramOutputConfiguration(
string Id,
string Description,
string TargetHost,
int TargetPort,
string SharedTextureName,
int TargetWidth,
int TargetHeight,
int TargetFramesPerSecond,
MimirEveProgramOutputTransport Transport,
bool UsesWebKit,
bool DiagnosticOnly,
string[] RequiredEnvironment,
string Notes);
public static class MimirEveProgramOutputConfigurations
{
public const string DefaultSharedTextureName = "Global\\MimirFensalirProgramTexture";
public static MimirEveProgramOutputConfiguration NativeSharedTexture { get; } = new(
"eve-native-d3d12-hardware-stream",
"Production direction: Fensalir copies the completed D3D12 backbuffer into a named shared texture; a hardware encoder consumes that texture and EVE displays decoded frames natively.",
"eve",
44044,
DefaultSharedTextureName,
1920,
1440,
60,
MimirEveProgramOutputTransport.D3D12SharedTextureHardwareEncode,
UsesWebKit: false,
DiagnosticOnly: false,
RequiredEnvironment:
[
"FENSALIR_PROGRAM_OUTPUT_D3D12=1",
$"FENSALIR_PROGRAM_OUTPUT_NAME={DefaultSharedTextureName}"
],
"EVE owns decode/composite only. It does not own layout, DOM, timing authority, or Chromium compatibility.");
public static MimirEveProgramOutputConfiguration MoonlightProbe { get; } = NativeSharedTexture with
{
Id = "eve-moonlight-probe",
Description = "Latency probe only: Sunshine/Moonlight can validate network and decode budget before the custom encoder path is finished.",
Transport = MimirEveProgramOutputTransport.SunshineMoonlightProbe,
SharedTextureName = "",
DiagnosticOnly = true,
RequiredEnvironment = [],
Notes = "This proves the EVE display/network budget, not Mimir's shared-texture authority."
};
public static IReadOnlyList<MimirEveProgramOutputConfiguration> BuiltIn { get; } =
[
NativeSharedTexture,
MoonlightProbe
];
}

View file

@ -4,6 +4,7 @@ public enum MimirObsVideoPublicationKind
{
Spout2,
SharedD3D12Texture,
EveNativeD3D12Stream,
SrtDiagnosticBridge,
WindowCaptureDiagnostic
}
@ -74,10 +75,20 @@ public static class MimirObsPublicationConfigurations
TargetPresentationDelaySeconds: 1.5,
DiagnosticOnly: true);
public static MimirObsPublicationConfiguration EveNativeProgram { get; } = NativeProgram with
{
Id = "eve-native-d3d12-stream",
Description = "EVE-facing native program output: Fensalir publishes a shared D3D12 texture for hardware encode; EVE receives decoded pixels without WebKit layout authority.",
VideoKind = MimirObsVideoPublicationKind.EveNativeD3D12Stream,
VideoSourceName = MimirEveProgramOutputConfigurations.DefaultSharedTextureName,
DiagnosticOnly = false
};
public static IReadOnlyList<MimirObsPublicationConfiguration> BuiltIn { get; } =
[
NativeProgram,
TextureInteropProgram,
EveNativeProgram,
DiagnosticSrtBridge
];
}

View file

@ -119,3 +119,4 @@
{"ts": "2026-05-25T13:56:03+01:00", "type": "decision", "status": "ok", "note": "Fensalir spectrum visualization authority split: Mimir now emits AquariumBufferFieldFrame spline tube fields as the real buffer-domain contract, with tangent/curvature/normal/derivative appearance and probe policy for future compute SDF splat reservoir lowering. AquariumSplineFrame remains only the immediate Catmull-Rom preview witness until compute lowering owns rendering."}
{"ts": "2026-05-25T15:55:00+01:00", "type": "decision", "status": "ok", "note": "Fensalir/Mimir spectrum visualization moved from C# spline authority to DSL-authored texture field authority. config/mimir-spectrum-field.aquafield binds a rolling spectrum texture, declares surface graph nodes, and asks for texture-dimension splinefield lowering. Fensalir now compiles Aquarium field DSL text, uploads texture samples/program packets, and ProgramMode=3 in D3D12FractalReservoirCompute emits stochastic reservoir splats from the texture field. Current canary is mechanically through the reservoir at 131072 splats with low CPU record time, but visual framing/material is still not the final beautiful spectrum surface."}
{"ts": "2026-05-25T17:43:25+01:00", "type": "decision", "status": "ok", "note": "Fensalir direct splinefield correction: texture-derived tube trails are direct SDF envelope surfaces, not point-splat fractal dust. AquariumFieldScriptCompiler supports direct; D3D12Renderer now derives AquariumSplineFrame tube-envelope trails from BufferFieldFrame texture spline programs, the spline pipeline declares triangle topology, and D3D12SplinePS writes color, metadata/control, and reservoirGuide outputs. Mimir capture artifacts/runtime/mimir-direct-sdf-tube-spectrum.png proves the DSL-authored ASIO spectrum appears through the direct SDF tube path with ~0.64 ms record CPU in the canary."}
{"ts": "2026-05-25T18:01:04+01:00", "type": "decision", "status": "ok", "note": "EVE native program output is now a D3D12 shared-texture contract: Fensalir owns completed backbuffer pixels and publishes Global\\MimirFensalirProgramTexture when FENSALIR_PROGRAM_OUTPUT_D3D12=1; Mimir records the EVE publication profile and WebKit remains forbidden as pixel/layout authority."}

View file

@ -46,7 +46,10 @@ invariants:
to line up feeds and crunch data before OBS-facing output is emitted.
- Typed views may index the rolling buffer, but no per-kind ring owns
retention.
- Fensalir owns production UI, GPU fusion, D3D12 interop, and Spout2 output.
- Fensalir owns production UI, GPU fusion, D3D12 interop, Spout2 output, and
the EVE shared D3D12 program-output texture.
- EVE fullscreen output must use native decode/composite over Fensalir-owned
program pixels; WebKit/DOM layout is forbidden as pixel authority.
- Faust/native DSP owns hot audio alignment, separation, spatialization, and
stems.
- Local secrets remain untracked.
@ -63,6 +66,11 @@ accepted_design:
direct native ingest, process bridge ingest, and video capture driver seams.
- `MimirVideoFrameDescriptor` carries width, height, pixel format, stride,
device timestamp, and optional native/GPU handle.
- `MimirEveProgramOutputConfigurations.NativeSharedTexture` records the
EVE-facing program-output contract: Fensalir publishes
`Global\MimirFensalirProgramTexture` when
`FENSALIR_PROGRAM_OUTPUT_D3D12=1`; EVE receives decoded native pixels and
owns only final composite/input uplink.
- `MimirAudioBlockDescriptor` carries sample rate, channels, sample format,
frame count, timestamp, and optional native handle.
- `MimirFrameEventProcessStreamSource` is a temporary diagnostic adapter for