{
  "product": "Eidolon",
  "version": "0.1.0",
  "package": "Eidolon-0.1.0-macOS-universal",
  "generated_by": "tools/release/generate_manifest.py (never hand-edited)",
  "provenance": {
    "commit": "a15fead8ce4c6addfaa9f390cc895896216b03ce",
    "build_type": "Release",
    "generator": "Ninja",
    "single_build": true,
    "note": "All hashes below come from one build of this one commit."
  },
  "platform": {
    "os": "macOS",
    "architectures": "x86_64 arm64",
    "universal": true,
    "requested_deployment_target": "10.15",
    "effective_minimum_os_version_per_slice": {
      "x86_64": "10.15",
      "arm64": "11.0"
    },
    "why_requested_differs_from_effective": "arm64 macOS does not exist below 11.0, so the linker clamps the 10.15 request to 11.0. That is correct behaviour, not a fault. It happens SILENTLY on this toolchain -- no warning is emitted -- so the effective floor is read off the built binary with otool -l LC_BUILD_VERSION rather than trusted from the requested value. The request is held at 10.15 rather than raised to 11.0 so it is already right for the x86_64 slice, which now ships in this universal binary. It cannot go lower: tools/EidolonPresetTransitionProbe.cpp, tools/EidolonMasterAnalogueProbe.cpp and tools/EidolonStage4CapturedNull.cpp use std::filesystem, which libc++ marks unavailable below macOS 10.15, so a lower request stops the build.",
    "x86_64_status": "SHIPPED -- universal binary, both slices held to the same quality bar",
    "x86_64_status_detail": "This is a UNIVERSAL binary. PR #287 guarded the <arm_neon.h> includes in Source/DSP/DriftNoise.h and Source/DSP/AdditiveOscillator.h with a bit-exact scalar fallback so both slices build from one tree, and Travis ruled (2026-08-29) to ship both after A/B-ing them and finding each meets the engine's quality bar. The slices do NOT produce identical bytes and cannot without moving arm64: measured across the 34-program factory suite the x86_64 render diverges from arm64 by -19.5 dBFS peak / -44 dBFS rms, reaching signal level on sustained drone/cloud patches (P07 +1.5 dB). That divergence is emergent -- every Catch2 case passes bit-for-bit on both slices, but the nonlinear feedback/drift chain amplifies a last-bit arch seed (FMA fusion, which arm64 does in one rounding and baseline x86-64 does not; #287 proved libm bit-identical across arches, so the residual second source is vectorisation/summation order + denormal handling, NOT libm) over seconds of audio. -ffp-contract=off is not a remedy: residual -30.8 dBFS cross-arch, and it moves arm64 itself off this render by -19.5 dBFS. The ruling's standard is NOT bit-identity -- it is the same quality bar: tools/pipeline/check_x86_quality.sh holds the x86_64 slice to the SAME absolute thresholds arm64 passes (metrics_plus caps, spectral per-step budget, onset max-jump), fail-closed. Measurement + A/B: the universal-macos-build and universal-ship-and-x86-quality-gate hand-backs.",
    "consequence": "This package is universal: it runs on Apple Silicon Macs (arm64, macOS 11.0 or newer) and on Intel Macs (x86_64, macOS 10.15 or newer). The effective OS floor differs per slice -- see effective_minimum_os_version_per_slice -- because arm64 macOS does not exist below 11.0."
  },
  "code_signing": {
    "current_state": "ad-hoc signed, NOT notarised",
    "signature": "adhoc",
    "team_identifier": null,
    "notarised": false,
    "identifier": "com.TravisInskeep.Eidolon",
    "status_is_a_ruling_not_a_gap": "Ad-hoc signing is the SHIPPED STATE BY RULING (Travis, 2026-08-26), not an unfinished step. Read it as a decision, not a gap. The reason it was ruled rather than merely deferred: notarisation requires a Developer ID Application certificate, and this machine has none. security find-identity -p codesigning returns a self-signed theming certificate and an Apple Development certificate; the latter signs builds for the developer's own registered machines and Apple's notary service rejects it for distribution. Obtaining a Developer ID certificate requires paid Apple Developer Program enrolment, whose approval is not on this project's critical path. The consequence is accepted deliberately: a downloaded copy is quarantined by Gatekeeper and INSTALL.md section 2 applies PERMANENTLY, not temporarily. docs/release/NOTARIZE.md is retained as the runnable procedure should a Developer ID certificate be obtained later; because signing is a post-packaging transformation it can be applied to the distributed copies without rebuilding or re-rendering.",
    "note_on_hashes": "Signing rewrites the signature blob inside the Mach-O, so running NOTARIZE.md WILL change every inner_macho_sha256 above. That is expected. The render hashes are unaffected -- signing does not touch the audio."
  },
  "formats": [
    {
      "format": "VST3",
      "bundle": "Eidolon.vst3",
      "inner_macho": "Eidolon.vst3/Contents/MacOS/Eidolon",
      "inner_macho_sha256": "b676f92f73e9c5130148bce978872195bcce7b3e25940c3c9d11a831c9cf5496",
      "inner_macho_bytes": 12410432,
      "architectures": "x86_64 arm64",
      "minos_per_slice": {
        "x86_64": "10.15",
        "arm64": "11.0"
      }
    },
    {
      "format": "AU",
      "bundle": "Eidolon.component",
      "inner_macho": "Eidolon.component/Contents/MacOS/Eidolon",
      "inner_macho_sha256": "a3c911f3488f4df3188ae389e0bd990da508d729ddab91de9a27cfc8436eeb66",
      "inner_macho_bytes": 12348032,
      "architectures": "x86_64 arm64",
      "minos_per_slice": {
        "x86_64": "10.15",
        "arm64": "11.0"
      }
    },
    {
      "format": "CLAP",
      "bundle": "Eidolon.clap",
      "inner_macho": "Eidolon.clap/Contents/MacOS/Eidolon",
      "inner_macho_sha256": "1ee0f741e24cf140ae2f6e8dbb8d35b94150d1fd8e4d6faea7317fd8bea184a0",
      "inner_macho_bytes": 12390400,
      "architectures": "x86_64 arm64",
      "minos_per_slice": {
        "x86_64": "10.15",
        "arm64": "11.0"
      }
    }
  ],
  "verify": "shasum -a 256 <bundle>/Contents/MacOS/Eidolon  # compare to inner_macho_sha256",
  "audio_invariance_across_this_build": {
    "claim": "Factory-suite render is BYTE-IDENTICAL across the CMakeLists deployment-target fix",
    "method": "CMAKE_OSX_ARCHITECTURES and CMAKE_OSX_DEPLOYMENT_TARGET were the only variable: the whole 34-program factory suite was rendered from a Release build BEFORE the CMakeLists change, the guarded-FORCE fix was applied, Release was rebuilt, and the identical suite was re-rendered and compared by sha256. One variable at a time, gate before change.",
    "render_sha256_before": "d881c13b4876e69920b8a9d02417e847c9fc411d61fd39d189bac7195b3a9efe",
    "render_sha256_after": "d881c13b4876e69920b8a9d02417e847c9fc411d61fd39d189bac7195b3a9efe",
    "identical": true,
    "scope": "arm64 only. The render hashes above are the arm64 slice: the arm64 render is byte-identical across the deployment-target fix and to an arm64-only build. The x86_64 slice is deliberately NOT byte-compared -- it diverges from arm64 by design (#293) and is instead held to the same absolute quality bars by tools/pipeline/check_x86_quality.sh. Cross-architecture byte-comparison would be structurally invalid regardless."
  },
  "host_validation": {
    "status": "Travis will validate all three formats himself when ready.",
    "prior_result": "AU passed auval; VST3 and CLAP were dlopen-loaded successfully in a prior pass.",
    "this_pass": "No host validation was re-run here."
  }
}
