Commit Graph

3 Commits

Author SHA1 Message Date
Fr0zka 0379d59c1c docs: AUDIT C9 — the FP default differs BY TOOLCHAIN, not just "fast is allowed to drift"
Jahni asked the right question: does the same seed produce identical results
across OS builds today? Checking the other toolchain made the answer sharper and
worse than what C9 originally said.

ClangToolChain.cs (Linux, Mac, Windows-with-Clang):

    case FPSemanticsMode.Default: // Default to precise FP semantics.
    case FPSemanticsMode.Precise: Arguments.Add("-ffp-contract=off");

and VCToolChain forces Precise when Windows uses Clang. So the same
FPSemanticsMode.Default resolves to OPPOSITE float models per toolchain, and
Windows/MSVC is the only imprecise configuration in the engine's defaults. Two
builds of identical source are not merely permitted to diverge -- they are
compiled under different rules.

Also added, so the entry does not over-fear itself:
- Calibration: 0 of 20000 samples crossed the isosurface under a 1-ULP
  perturbation, so divergence means occasional single-voxel surface differences,
  not different terrain. The case that bites is topological (a cave pinch-point
  connecting on one build and not the other), which is rare and unreproducible --
  the expensive kind.
- Precise everywhere still would not guarantee cross-platform bit-identity:
  FMath::Sin/Cos route to platform libm, which is not bit-standardised. It closes
  the large gap, not every gap.
- The knob would ALIGN Windows with every other platform rather than being a
  one-sided cost -- but still must not be turned speculatively.
- The claim is inferred, not measured. The cheap decisive test is one Windows
  build with FPSemantics = Precise: if MazeEquivalence's 454-sample residue
  vanishes, the FP model is confirmed as the sole cause.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 14:19:42 +02:00
Fr0zka af5f2103b3 test: the Maze residue is /fp:fast, not port drift — encode the real bar
The bisect settled it. The difference survives every stage removal down to
"corridors + carve ONLY", which is character-for-character transcribed code, so
it is not in anything the decomposition added.

Cause, read out of the engine rather than assumed (VCToolChain.cs):

    case FPSemanticsMode.Default: // Default is imprecise FP semantics.
    case FPSemanticsMode.Imprecise: Arguments.Add("/fp:fast"); break;

with UBT's own doc: "the compiler is allowed to transform math expressions in
ways that might result in differently rounded results". Identical source in two
translation units may reassociate differently, worth ~1 ULP. It shows up on
exactly the ~2% of samples inside the SDF blend shell, where Blend - Sdf
catastrophically cancels; outside it Carve is exactly 0 or 1 and both agree.

So MazeEquivalence now grades what it can actually assert:
  - hard fail  : any isosurface crossing (geometry moves)
  - info       : differences at ULP scale (the unavoidable floor)
  - warn       : anything larger, which IS port drift, and runs the bisect
A test that warns on every port would get ignored by the port that matters.

Recorded in OPSTACK-PLAN 2.6, and as AUDIT C9 for the part that outlives this
refactor: ARCHITECTURE 9.1's "every peer regenerates identically" holds only
between bit-identical binaries under /fp:fast. Fine for one build on one
platform; a real desync source for a Linux server plus Windows clients both
regenerating authoritative geometry. The FPSemantics::Precise knob exists but
must not be turned speculatively -- it blocks the vectorisation T2.a was chasing,
on the hot loop, for an unmeasured cost.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 14:15:43 +02:00
Fr0zka 3128852d4e chore: track the design docs in git (.gitignore !*.md)
AUDIT P1: every markdown design doc except CODEMAP.md was untracked, so
ARCHITECTURE / AUDIT / OPSTACK-PLAN / fable-idea / REVIEW_FINDINGS lived
only on disk. Replaces the single !CODEMAP.md exception with !*.md.

Also makes OPSTACK-PROGRESS.md commits actually record something, which
the unattended crash-safety discipline depends on.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 01:39:21 +02:00