============================================================
 RockyGuard Library - Customer Package (macOS x64)
============================================================

This zip contains the macOS x86_64 (Intel) build of RockyGuard. For the
Windows x64 build download rockyguard-vX.Y.Z-windows-x64-customer.zip;
for Linux, rockyguard-vX.Y.Z-linux-x64-customer.zip. All three packages
share the same C++ API and license-file format; see
docs/Customer_Documentation.txt for cross-platform coverage.

PLATFORM REQUIREMENTS:

  x86_64 (Intel) macOS 11 "Big Sur" or newer. The binaries are Mach-O
  x86_64: on Apple Silicon (M1/M2/M3...) they run transparently under
  Rosetta 2. A native arm64 build is not in this zip -- request one from
  the vendor if you need Apple Silicon native.

  To build the examples or link the library into your app you need the
  Xcode Command Line Tools (clang/clang++) and CMake 3.16+:
    xcode-select --install

  SELF-CONTAINED -- NO HOMEBREW REQUIRED. The library statically links
  libc++ and OpenSSL, so it has no third-party runtime dependency. You
  do NOT need to `brew install openssl`. Confirm with:
    otool -L tools/license_verify
  It should list only /System/Library/Frameworks/... and /usr/lib/...
  (libSystem, libc++). If you ever see a /usr/local/opt/openssl or
  /opt/homebrew path there, the build was mis-linked -- contact the
  vendor.

CONTENTS:

  include/rockyguard/       Public headers
    rockyguard.h              Single-include convenience header
    version.h                 Library version macros (auto-generated)
    types.h                   Enums and result types
    license_error.h           Error-code catalog lookups (v1.4+)
    license.h                 License data model
    license_verifier.h        License verification
    license_asset.h           Load-bearing asset decryption (v1.4+)
    hardware_fingerprint.h    Machine hardware fingerprinting
    floating_client.h         Floating license client (Premium)
    diagnostics.h             Licence Inspector / health-check API (v1.4+)
    export.h                  Shared-library export macros

  lib/static/
    librockyguard.a         Static library. Contains RockyGuard code
                            ONLY -- you must also link the two OpenSSL
                            archives from deps/lib/ AND two macOS
                            frameworks. See LINKING.

  lib/shared/
    librockyguard.dylib     Shared library (OpenSSL statically linked
                            INTO this one -- nothing extra to link or
                            ship alongside it). Its install name is
                            @rpath/librockyguard.dylib.
    librockyguard.sig       Integrity signature (ship next to the .dylib)

  tools/
    license_keygen              Generate your Ed25519/RSA keypair
    license_create              Create end-user licenses
    license_verify              Verify and inspect license files
    rg_fingerprint              Print machine hardware fingerprint
    rg_floating_server          Floating license server (Premium tier only)
    floating_server_config.yaml Sample server config file
    rg_floating_client          Floating license client (Premium tier only)
    rg_inspect                  Licence Inspector: collects a full
                                licensing diagnostic from the end user's
                                machine and writes ONE encrypted file
                                they mail to support. Run it before
                                opening a ticket.
    rg_bind_asset               Build-time asset binder for load-bearing
                                licences: seals an asset under a data key
                                and emits a C header of ciphertext for
                                your build (guide section 6.5).
    rg_bind_asset.cpp           Its source -- rebuilds against deps/ alone.
    rg_bind_lint                Python linter: catches integrations that
                                collapse the load-bearing pattern back
                                into a flippable boolean. Run as
                                "python3 tools/rg_bind_lint <src>".

  deps/
    include/openssl/            Bundled OpenSSL headers, matching the
                                version the library was built against
    lib/libcrypto.a             REQUIRED when you static-link
    lib/libssl.a                REQUIRED when you static-link
                                librockyguard.a. Both archives, and in
                                this order: libssl.a before libcrypto.a
                                on the link line, because ld resolves
                                left to right and libssl depends on
                                libcrypto. Not needed for the shared
                                (.dylib) path, which has OpenSSL inside it.

  examples/
    CMakeLists.txt                  Build script for the examples
    node_locked_example.cpp         Node-locked license verification example
    hidden_key_example.cpp          Node-locked example with the public key
                                    embedded as split/masked tables
    hidden_public_key.h             Generated masked key (PLACEHOLDER -- regen
                                    from your own key with embed_public_key.py)
    embed_public_key.py             Generator: PEM public key -> masked header
    health_check_example.cpp        Diagnostics/self-check pattern
    loadbearing_asset_example.cpp   Load-bearing licence: open an asset the
                                    program needs with a key taken from the
                                    validated licence (LicenseAsset), instead
                                    of branching on the verdict. Run with
                                    --encrypt to seal an asset at build time.
    bound_asset.h                   Header-only sealer behind --encrypt and
                                    rg_bind_asset. Build-time only; your app
                                    opens assets with LicenseAsset.
    FEATURES.template.md            Feature-flag register template -- copy to
                                    your repo root as FEATURES.md.
    rg_floating_client.cpp     Floating license client example (Premium)
    inspector/                      Licence Inspector source pair (rg_inspect
                                    + rg_report_read) -- build with your own
                                    keys; see inspector/README.txt

  cmake/
    RockyGuardBindAsset.cmake       rockyguard_bind_asset(): one CMake call
                                    that seals an asset at build time and
                                    hands your target the ciphertext header.

  docs/
    Customer_Documentation.txt/pdf          Library documentation
    Customer_API_Reference.txt/pdf          API reference
    RockyGuard_License_Agreement.txt/pdf    Software License Agreement

  AI_INTEGRATION_GUIDE.md                   For AI coding assistants
                                            (Claude, ChatGPT, Cursor,
                                            Copilot, Gemini, Cody, ...).
                                            Tell your AI: "Read
                                            AI_INTEGRATION_GUIDE.md and
                                            integrate RockyGuard into
                                            this project."

  portal/
    start.sh                Launch the licensing-management web app
    README.md               Portal setup and daily workflow. Drop your
                            vendor_license.json + vendor_private.pem into
                            Settings on first run, then issue licenses to
                            your end users from a browser at
                            127.0.0.1:8765.

QUICK START:

  BEFORE STEP 3 YOU NEED A FILE THAT IS NOT IN THIS ZIP.
  vendor_license.json is issued to your organisation by Rocky Software
  Inc. and sent by email; it is deliberately not bundled, because it is
  specific to you. Request it now if you do not have it -- the stated
  turnaround is one business day, and step 3 onward cannot run without
  it. Details in Customer_Documentation section 2.2. Steps 1 and 2
  below need nothing from us and can be done while you wait.

  WHERE TO RUN THESE. Work from a directory YOU own -- not this
  extracted package. The tools write their output to the current
  directory, so running them from here drops your private signing key
  inside a folder you are expected to delete and re-extract. Set a
  variable pointing back at the package once, then use it everywhere:

       RG="$(pwd)"                 # run this while still in the package
       mkdir -p ~/licensing/myproduct && cd ~/licensing/myproduct

  1. macOS quarantines files from a downloaded zip. If a tool is
     blocked ("cannot be opened because the developer cannot be
     verified"), clear the quarantine bit once, and make the tools
     executable if your unzip did not preserve the x bit:
       xattr -dr com.apple.quarantine "$RG"/tools
       chmod +x "$RG"/tools/*

  2. Generate your keypair (once):
       "$RG/tools/license_keygen" --private private.pem --public public.pem

  3. Create end-user licenses (vendor license required, CLI tool):
       "$RG/tools/license_create" \
         --vendor-license vendor_license.json \
         --key private.pem --id "LIC-001" \
         --licensee "User" --product "App" \
         --fingerprint-value "<end user's fingerprint>" \
         --expires "2027-12-31T23:59:59Z"

  4. In your end-user application (NO vendor license needed):
       std::optional<LicenseVerifier> v;      // not copyable/movable
       try { v.emplace(PUBLIC_KEY); }         // the ONLY call that throws
       catch (const std::runtime_error& e) {
           std::cerr << e.what() << "\n"; return 1;
       }
       auto result = v->load("license.json");
       result = v->check_node_locked();

     The try/catch is not decoration. A PUBLIC_KEY literal that was
     truncated or line-wrapped when pasted compiles fine and throws at
     construction; uncaught, that is std::terminate() on your end user's
     machine. See docs/Customer_Documentation.txt section 12.2.

LINKING:

  The fastest correct route is to copy examples/CMakeLists.txt, which
  already defines the imported targets, both OpenSSL libraries, and the
  macOS frameworks. The snippets below are the minimum equivalent.

  Static (recommended):
    In your CMakeLists.txt:
      target_include_directories(your_app PRIVATE
          path/to/include
          path/to/deps/include)
      target_link_libraries(your_app PRIVATE
          path/to/lib/static/librockyguard.a
          path/to/deps/lib/libssl.a
          path/to/deps/lib/libcrypto.a
          "-framework IOKit" "-framework CoreFoundation")
    The shipped librockyguard.a contains the RockyGuard code only;
    OpenSSL is bundled in deps/ and must be linked explicitly (ssl
    before crypto). On macOS the fingerprint code uses IOKit +
    CoreFoundation, so link both frameworks -- these are the macOS
    equivalents of Linux's `pthread dl`.

  Shared (.dylib):
    In your CMakeLists.txt:
      target_compile_definitions(your_app PRIVATE ROCKYGUARD_SHARED_LIB)
      target_include_directories(your_app PRIVATE path/to/include)
      target_link_libraries(your_app PRIVATE
          path/to/lib/shared/librockyguard.dylib)
      # librockyguard.dylib's install name is @rpath/librockyguard.dylib,
      # so tell your_app where to find it at runtime (there is no
      # LD_LIBRARY_PATH on macOS -- use an rpath or co-locate):
      set_target_properties(your_app PROPERTIES
          BUILD_RPATH   "path/to/lib/shared"
          INSTALL_RPATH "@loader_path/../lib/shared")
      # ...or ship your_app next to librockyguard.dylib and use
      # INSTALL_RPATH "@loader_path".

    Ship with your application:
      - librockyguard.dylib
      - librockyguard.sig  (integrity signature; must be next to the .dylib)
      OpenSSL is statically linked into librockyguard.dylib; no separate
      libcrypto/libssl runtime to ship.

  Verify self-containment before you ship: `otool -L your_app` should
  list only /System frameworks + /usr/lib. Inspect the RockyGuard load
  path with `otool -l your_app | grep -A2 LC_RPATH`.

DIFFERENCES FROM THE WINDOWS BUILD:

  - Extension: .dylib instead of .dll, no extension on tools (not .exe)
  - No .lib import library (macOS links the .dylib directly)
  - No libcrypto/libssl runtime files to ship (statically linked)
  - Runtime library search uses @rpath / @loader_path, not PATH, and
    there is no LD_LIBRARY_PATH -- set an rpath (install_name_tool or the
    CMake INSTALL_RPATH above) or co-locate the .dylib with your binary
  - No registry-based time anchor: macOS uses file anchors under
    ~/Library/Application Support/RockyGuard/
  - Hardware fingerprint fields: MAC from IOKit (en0/en1), CPU ID from
    the machdep.cpu.brand_string sysctl, disk serial from the IOKit
    NVMe/AHCI Device Characteristics, motherboard UUID from
    IOPlatformUUID. No root or extra entitlements required; an empty
    field is hashed as the empty string and skipped in match scoring, so
    a missing field just lowers the hardware-match score rather than
    breaking verification.
