Attach Move proof surface to runtime frame

This commit is contained in:
Meta Vens 2026-07-08 22:42:20 +01:00
commit 02c6bfc533
6 changed files with 188 additions and 5 deletions

View file

@ -90,6 +90,13 @@ a named invariant that the native runtime cannot protect yet.
--move-proof-pipeline-smoke` proves that shape against the native reservoir
debug DLL; live hardware and presented-frame capture still need to call this
primitive instead of hand-assembling a parallel path.
- `MimirRuntime` is now the live Fensalir attachment point for proof surfaces.
`PublishMoveProofSurface` accepts the Mimir-owned
`mimir.move_proof_surface.v1` document, `CreateFrame` composes its
observer-only `move-proof-*` splines into `AquariumFrame.Scene.SplineFrame`,
and `Mimir.BufferSmoke --move-proof-runtime-frame-smoke` proves the frame is
empty before publish, contains the proof splines after publish, and clears
without leaving a repair loop behind.
- `MimirMoveCalibrationProtocol` publishes the typed calibration preflight for
Starfire/Nightwing Moves: required Muninn evidence streams, optional
Quest headset/controller pose witnesses, stillness/sweep/validation phases, and
@ -398,10 +405,11 @@ a named invariant that the native runtime cannot protect yet.
becomes a deterministic timeline anchor before the actuator moves samples.
6. Prove the bioacoustic hybrid fallback through real loopback and microphones
with probe durations long enough to keep loopback and mic windows live.
7. Attach the Move proof surface to the live runtime/Fensalir presentation path:
ingest real Muninn Nightwing and Starfire evidence, require calibrated
optical witnesses, publish `mimir:starfire:move-pose:<sequence>`, and capture
a presented Fensalir frame/probe for the same sequence.
7. Wire live Move proof production into `MimirRuntime.PublishMoveProofSurface`:
ingest real Muninn Nightwing and Starfire evidence through
`MimirMoveProofPipeline`, require calibrated optical witnesses, publish
`mimir:starfire:move-pose:<sequence>`, and capture a presented Fensalir
frame/probe for the same sequence.
8. Bind Fensalir UI to the synchronization hub so buffer depth, stream cadence,
source timestamps, and output settings are visible and adjustable.
9. Implement the Mimir program scene graph as the shared commit primitive for

View file

@ -212,6 +212,12 @@ from one Muninn CultMesh shared-memory frame it performs native admission,
Mimir fusion, pose-frame creation, proof-surface creation, and Fensalir probe
lowering. Live Nightwing/Starfire wiring should call this owner path rather
than preserving separate manual actions and programmatic proof paths.
`MimirRuntime` now owns the actual Fensalir presentation attachment for the
proof surface: `PublishMoveProofSurface` stores the latest Mimir-owned
`mimir.move_proof_surface.v1`, and `CreateFrame` merges its observer-only
`move-proof-*` probe splines into `AquariumFrame.Scene.SplineFrame` beside the
audio spectrum preview. Fensalir renders this frame; it still does not decide
proof.
## Program Composition

View file

@ -2,10 +2,12 @@ using System.Diagnostics;
using System.Numerics;
using System.Security.Cryptography;
using System.Text.Json;
using Aquarium.Engine;
using GameCult.Caching;
using GameCult.Caching.MessagePack;
using GameCult.Mesh;
using MessagePack;
using Mimir.Runtime;
using Mimir.Runtime.Synchronization;
if (args.Any(arg => string.Equals(arg, "--chirplet-self-test", StringComparison.OrdinalIgnoreCase)))
@ -146,6 +148,11 @@ if (args.Any(arg => string.Equals(arg, "--move-proof-pipeline-smoke", StringComp
ParseStringOption(args, "--native-reservoir", DefaultNativeReservoirPath()));
}
if (args.Any(arg => string.Equals(arg, "--move-proof-runtime-frame-smoke", StringComparison.OrdinalIgnoreCase)))
{
return RunMoveProofRuntimeFrameSmoke();
}
if (args.Any(arg => string.Equals(arg, "--move-calibration-protocol-smoke", StringComparison.OrdinalIgnoreCase)))
{
return await RunMoveCalibrationProtocolSmokeAsync(
@ -2223,6 +2230,106 @@ static int RunMoveProofSurfaceSmoke()
: 1;
}
static int RunMoveProofRuntimeFrameSmoke()
{
var surface = CreateMoveProofSurfaceSmokeDocument();
var runtime = new MimirRuntime(
new AquariumRuntimeOptions(Headless: true, CultCachePath: null),
new MimirSynchronizationSettings());
var emptyFrame = runtime.Frame;
runtime.PublishMoveProofSurface(surface);
var proofFrame = runtime.Frame;
var proofSplineCount = proofFrame.Scene.SplineFrame.Splines.Count(spline =>
spline.Id.StartsWith("move-proof-", StringComparison.Ordinal));
runtime.ClearMoveProofSurface();
var clearedFrame = runtime.Frame;
Console.WriteLine(
$"move-proof-runtime-frame-smoke proof={surface.ProofId} frame={surface.FensalirFrameId} verdict={surface.Verdict} before={emptyFrame.Scene.SplineFrame.Splines.Count} proofSplines={proofSplineCount} afterClear={clearedFrame.Scene.SplineFrame.Splines.Count}");
return emptyFrame.Scene.SplineFrame.Splines.Count == 0 &&
proofFrame.Scene.SplineFrame.HasInput &&
proofSplineCount >= 3 &&
proofFrame.Scene.SplineFrame.Splines.Any(spline => spline.Id.Contains("move-0xA11CE-79", StringComparison.Ordinal)) &&
clearedFrame.Scene.SplineFrame.Splines.Count == 0
? 0
: 1;
}
static MimirMoveProofSurfaceDocument CreateMoveProofSurfaceSmokeDocument()
{
var pose = new MimirMoveControllerPoseDocument(
PoseId: "move:0xA11CE:79",
WandId: "move:0xA11CE",
TrackingSpaceId: "mimir-stage-space",
CalibrationId: "mimir-move-stage-calibration-v1",
FusionAuthorityId: "mimir.runtime.move-fusion",
SourceTimestampNs: 1_781_202_600_004_000_000,
EstimatedAtNs: 1_781_202_600_006_200_000,
Sequence: 79,
PositionMeters: new MimirVector3Snapshot(0.0, 1.1, 1.0),
Orientation: new MimirQuaternionSnapshot(0.0, 0.0, 0.0, 1.0),
LinearVelocityMetersPerSecond: new MimirVector3Snapshot(0.0, 0.0, 0.0),
AngularVelocityRadiansPerSecond: new MimirVector3Snapshot(0.02, -0.01, 0.04),
Confidence: 0.82,
LatencyMilliseconds: 2.2,
Battery01: 0.72,
Buttons:
[
new MimirTrackingButtonSnapshot("move", true, 1.0),
new MimirTrackingButtonSnapshot("trigger", true, 0.5)
],
EvidenceStreamIds:
[
"witness:0x00000000000A11CE",
"witness:0x0000000000000B0B",
"controller:0x00000000000A11CE"
],
EvidenceKinds:
[
"optical-marker:triangulated",
"controller-state:buttons-imu",
"orientation:imu-unresolved"
],
ConsumerContract: "fensalir.move-controller-input");
var admission = new MimirMuninnMoveEvidenceAdmission(
FrameId: "muninn:nightwing:move-evidence:79",
ProducerPeerId: "muninn:nightwing",
PublishedAtNs: 1_781_202_600_005_000_000,
MimirReadAtNs: 1_781_202_600_005_700_000,
SampleCount: 3,
OpticalMarkerCount: 2,
ControllerStateCount: 1,
SourceTimeMinNs: 1_781_202_600_004_000_000,
SourceTimeMaxNs: 1_781_202_600_004_000_000,
ArrivalMinNs: 1_781_202_600_004_500_000,
ArrivalMaxNs: 1_781_202_600_005_700_000,
Handle: new MimirNativeSampleHandle(
SensorIdHash: 0xF00D,
TimestampNs: 1_781_202_600_004_000_000,
ArrivalNs: 1_781_202_600_005_700_000,
Sequence: 79,
PayloadHandle: 0xBEEF,
Flags: 0,
Reserved: 0),
ReservoirEdgeNs: 1_781_202_600_004_000_000,
ReservoirWindowStartNs: 1_781_197_600_004_000_000,
ReservoirMoveEvidenceCount: 1);
var poseFrame = MimirMovePoseStream.CreateFrame(
frameId: "mimir:starfire:move-pose:79",
producerPeerId: "mimir:starfire",
publishedAtNs: pose.EstimatedAtNs,
trackingSpaceId: pose.TrackingSpaceId,
calibrationId: pose.CalibrationId,
poses: [pose]);
return MimirMoveProofSurface.Create(
admission,
poseFrame,
"fensalir:starfire:presented-frame:79",
fensalirPresentedAtNs: 1_781_202_600_007_100_000);
}
static int RunMoveProofPipelineSmoke(string nativeReservoirPath)
{
const ulong leftWitnessHash = 0x00000000000A11CE;

View file

@ -62,6 +62,7 @@ direct
private IReadOnlyList<MimirAudioSynchronizationReport> lastAudioSynchronizationReports = [];
private IReadOnlyList<MimirAudioSpectrumSnapshot> lastAudioSpectra = [];
private readonly Queue<IReadOnlyList<MimirAudioSpectrumSnapshot>> spectrumHistory = new();
private MimirMoveProofSurfaceDocument? latestMoveProofSurface;
public MimirRuntime(AquariumRuntimeOptions options)
: this(options, MimirRuntimeConfiguration.Load())
@ -144,6 +145,9 @@ direct
: bufferFieldFrame.HasInput
? new Vector3(0.0f, 0.0f, 12.0f)
: new Vector3(0.0f, 0.0f, cameraZ + 12.0f);
var spectrumSplineFrame = ShouldRenderSpectrumPreviewSplines()
? BuildSpectrumSplineFrame()
: AquariumSplineFrame.Empty;
return new AquariumFrame(
new ViewFrame(Vector2.Zero, 24.0f),
cameraPosition,
@ -155,7 +159,7 @@ direct
TraceHeightFieldSurface = false,
UseStarfieldBackground = false,
BufferFieldFrame = bufferFieldFrame,
SplineFrame = ShouldRenderSpectrumPreviewSplines() ? BuildSpectrumSplineFrame() : AquariumSplineFrame.Empty,
SplineFrame = ComposeFensalirSplineFrame(spectrumSplineFrame, latestMoveProofSurface),
});
}
@ -166,6 +170,44 @@ direct
synchronization.AddSource(source);
}
public void PublishMoveProofSurface(MimirMoveProofSurfaceDocument surface)
{
ArgumentNullException.ThrowIfNull(surface);
latestMoveProofSurface = surface;
}
public void ClearMoveProofSurface()
{
latestMoveProofSurface = null;
}
public static AquariumSplineFrame ComposeFensalirSplineFrame(
AquariumSplineFrame baseFrame,
MimirMoveProofSurfaceDocument? moveProofSurface)
{
ArgumentNullException.ThrowIfNull(baseFrame);
if (moveProofSurface is null)
{
return baseFrame;
}
var proofFrame = MimirMoveProofSurface.BuildFensalirProbeFrame(moveProofSurface);
if (!baseFrame.HasInput)
{
return proofFrame;
}
if (!proofFrame.HasInput)
{
return baseFrame;
}
return new AquariumSplineFrame
{
Splines = baseFrame.Splines.Concat(proofFrame.Splines).ToArray()
};
}
public void Start()
{
Console.WriteLine($"Mimir runtime sync buffers: {synchronization.Summary()} @ {synchronization.Settings.BufferDuration.TotalSeconds:0.###}s audioSync={audioSyncSettings.Mode} reference={audioSyncSettings.ReferenceSourceId}");
@ -231,6 +273,8 @@ direct
panel.Readout("Audio sync state", DescribeAudioSyncState);
panel.Readout("Aligned audio", DescribeAlignedAudio);
panel.Readout("Chirplet reference", DescribeChirpletReference);
panel.Section("Move Proof");
panel.Readout("Latest proof", DescribeMoveProofSurface);
panel.Section("Live FFT");
panel.Readout("Spectrum cadence", () => sceneReady
? $"{lastAudioSpectra.Count} spectra fft={lastAudioSpectra.FirstOrDefault()?.FftSize ?? 0} analyze={lastSpectrumAnalysisMilliseconds:0.00}ms"
@ -246,6 +290,17 @@ direct
});
}
private string DescribeMoveProofSurface()
{
var surface = latestMoveProofSurface;
if (surface is null)
{
return "No Move proof surface published.";
}
return $"{surface.ProofId} verdict={surface.Verdict} confidence={surface.PoseConfidence:0.000} latency={surface.LatencyMilliseconds:0.00}ms chain={surface.MuninnEvidenceFrameId}->{surface.MimirEvidenceFrameId}->{surface.MimirPoseFrameId}->{surface.FensalirFrameId}";
}
private static AquariumRenderPlan CreateRenderPlan()
{
var app = new AquariumApp();

View file

@ -161,3 +161,4 @@
{"ts": "2026-07-08T22:21:57+01:00", "type": "verification", "status": "ok", "note": "Correction to the earlier Move marker camera evidence: after installing/using the x86_64-unknown-linux-gnu Rust target, Muninn's V4L2 YUYV Move marker camera producer compiled with cargo check -p muninn-daemon --target x86_64-unknown-linux-gnu. cargo test -p muninn-daemon passes 148 tests. Nightwing hardware live proof remains pending, so this proves owned producer code and target compatibility, not calibrated live pose."}
{"ts": "2026-07-08T22:28:32+01:00", "type": "implementation", "status": "ok", "note": "Added MimirMoveProofSurface as the first observer-only Fensalir-visible Move proof surface: it combines a Muninn evidence admission receipt, Mimir pose stream frame, and Fensalir presentation/probe timestamp into mimir.move_proof_surface.v1, lowers a dev AquariumSplineFrame probe, preserves source/publish/read/admit/fusion/present timing, and refuses to treat single-ray fallback as full pose. Verified dotnet build Mimir.Runtime, dotnet build Mimir.BufferSmoke, BufferSmoke --move-proof-surface-smoke, and BufferSmoke --move-fusion-smoke. Live Nightwing hardware, calibrated camera witnesses, and actual Fensalir presented-frame capture remain pending."}
{"ts": "2026-07-08T22:34:00+01:00", "type": "implementation", "status": "ok", "note": "Added MimirMoveProofPipeline as the shared commit primitive for one Move proof frame: it reads a Muninn CultMesh shared-memory evidence frame, admits samples to native move_evidence, runs MimirMoveFusion, emits the mimir:starfire move-pose frame, creates mimir.move_proof_surface.v1, and lowers the Fensalir spline probe in one pass. Verified dotnet build Mimir.Runtime, dotnet build Mimir.BufferSmoke, and BufferSmoke --move-proof-pipeline-smoke against the native reservoir debug DLL. This proves the reusable Mimir owner path; live Nightwing hardware, calibrated camera witnesses, and actual presented-frame capture remain pending."}
{"ts": "2026-07-08T22:41:32+01:00", "type": "implementation", "status": "ok", "note": "Attached the Move proof surface to the actual MimirRuntime/Fensalir frame path: MimirRuntime.PublishMoveProofSurface stores the latest Mimir-owned mimir.move_proof_surface.v1 document, CreateFrame composes its observer-only move-proof-* splines into AquariumFrame.Scene.SplineFrame, and the UI exposes a display-only proof readout. Verified dotnet build Mimir.Runtime, dotnet build Mimir.BufferSmoke, BufferSmoke --move-proof-runtime-frame-smoke, --move-proof-surface-smoke, and --move-proof-pipeline-smoke against the native reservoir debug DLL. Live Nightwing hardware, calibrated camera witnesses, and real presented-frame capture remain pending."}

View file

@ -143,6 +143,12 @@ accepted_design:
proof surface, and returns the Fensalir spline probe. Direct user actions,
programmatic smokes, and future live subscribers should use this same path
so the proof chain does not split into separately repaired truths.
- `MimirRuntime` now owns the actual Fensalir presentation attachment for
Move proof surfaces. `PublishMoveProofSurface` accepts the latest
Mimir-owned proof document, and `CreateFrame` composes its observer-only
`move-proof-*` probe splines into `AquariumFrame.Scene.SplineFrame` beside
the audio spectrum preview. Fensalir remains a renderer, not a proof
authority.
- `MimirMoveCalibrationProtocol` defines the runnable Starfire/Nightwing Move
calibration preflight as typed state: required Muninn Move evidence streams,
optional Quest headset/controller pose witnesses over USB,