Files
ObsidianDragon/docs/lite-wallet-backend-artifact-production-2026-05-18.md
DanS a78a13edf3 docs(lite): add v2 implementation plan, source-hygiene guard, and CLAUDE.md
- docs/lite-wallet-implementation-plan-v2-2026-06-04.md: vertical-slice plan that
  supersedes the v1 plan (now banner-marked); carries over the inherited artifact/
  signing/phase-2 design docs for reference.
- scripts/check-source-hygiene.sh: pre-commit/CI guard rejecting >80-char filenames
  and chained churn-token names, to stop the deleted "_plan"/"_batch" scaffolding
  from regrowing.
- CLAUDE.md: repository guidance for future sessions.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 21:15:11 -05:00

33 KiB

Lite Wallet Backend Artifact Production - 2026-05-18

Purpose

Phase 1 now has a concrete external artifact-production entry point for the SDXL-compatible lite backend. The wallet runtime still does not load, resolve, call, sign, upload, publish, or mutate backend artifacts.

The production handoff is:

  1. Build or inventory the Rust backend from external/SilentDragonXLite/lib.
  2. Capture a one-symbol-per-line exported-symbol inventory.
  3. Capture SHA-256, size, file metadata, source revision, builder label, and artifact-set provenance in a JSON manifest.
  4. Optionally capture read-only signature verification metadata after a release builder has already verified a sidecar signature.
  5. Pass the artifact path and symbol inventory into CMake when explicitly enabling the lite backend.

Script

Use scripts/build-lite-backend-artifact.sh.

Linux host build:

scripts/build-lite-backend-artifact.sh --platform linux

Clean reproducible Linux host build:

scripts/build-lite-backend-artifact.sh \
  --platform linux \
  --silentdragonxlitelib-dir /path/to/silentdragonxlite-cli/lib \
  --reproducible \
  --cargo-target-dir build/lite-backend-cargo-repro \
  --out-dir build/lite-backend-repro \
  --builder phase1-repro

Windows cross build with the GNU target:

scripts/build-lite-backend-artifact.sh --platform windows --rust-target x86_64-pc-windows-gnu

macOS builds must run on macOS or provide an explicit Apple Rust target from a configured cross toolchain:

scripts/build-lite-backend-artifact.sh \
  --platform macos \
  --rust-target x86_64-apple-darwin \
  --silentdragonxlitelib-dir /path/to/silentdragonxlite-cli/lib

To inventory an already-built artifact without running Cargo:

scripts/build-lite-backend-artifact.sh --platform linux --artifact /path/to/libsilentdragonxlite.a --no-build

To require read-only signature verification metadata after an external verifier has already checked the artifact:

scripts/build-lite-backend-artifact.sh \
  --platform linux \
  --artifact /path/to/libsilentdragonxlite.a \
  --no-build \
  --signature-required \
  --signature-file /path/to/libsilentdragonxlite.a.minisig \
  --signature-format minisign \
  --signature-verification-tool "minisign 0.11" \
  --signature-key-fingerprint "<reviewed-public-key-fingerprint>" \
  --signature-verified-sha256 "<artifact-sha256>"

The script writes:

  • build/lite-backend/<platform>/<artifact>
  • build/lite-backend/<platform>/lite-backend-symbols.txt
  • build/lite-backend/<platform>/lite-backend-artifact-manifest.json

It uses cargo build --locked --lib --release, CARGO_INCREMENTAL=0, and SOURCE_DATE_EPOCH when building. If SOURCE_DATE_EPOCH is not already set, the project commit timestamp is used.

--cargo-target-dir isolates Cargo output for clean-builder checks. --reproducible appends deterministic Rust --remap-path-prefix flags for the project, backend source, discovered or overridden silentdragonxlitelib source, Cargo home, and selected Cargo target directory. Use repeated --remap-path-prefix FROM=TO values only for additional source paths outside those defaults. Reproducibility should be checked by running the same command twice with different clean target directories and comparing the artifact SHA-256 and the filtered symbol inventory.

Portable Backend Dependency Path Plan

The checked-in wrapper at external/SilentDragonXLite/lib/Cargo.toml now references silentdragonxlitelib through the relative path ../silentdragonxlite-cli/lib. The maintained dependency source is vendored under external/SilentDragonXLite/silentdragonxlite-cli from revision 6a178c8d08d9c1c153fb22759a68177cdb787be7, with no .git or target/ build output imported and stale workflow conflict-backup files pruned from the vendored copy.

The Phase 1 portable builder contract is:

  • Preferred current path: build with --backend-dir external/SilentDragonXLite/lib and no --silentdragonxlitelib-dir; the script discovers the relative dependency, validates that it is package silentdragonxlitelib, remaps it in reproducible mode, and records it in manifest provenance with portable_dependency_override: false.
  • Acceptable comparison path: pass --silentdragonxlitelib-dir /path/to/silentdragonxlite-cli/lib to compare against an external maintained checkout. The script validates that directory, creates a generated wrapper under <out>/.prepared-backend/<platform>, patches only that generated Cargo.toml, and records portable_dependency_override: true.
  • Source cleanup status: the absolute dependency path has been removed from the checked-in wrapper; release runbooks should move from the override path to the relative source layout after Linux/Windows/macOS platform verification is refreshed.
  • Rejected release path: depending on /home/d/external/silentdragonxlite-cli/lib or any other builder-local absolute path in the committed backend source.

The artifact manifest records portable_dependency_override, cargo_build_source, silentdragonxlitelib_source, and silentdragonxlitelib_revision under provenance for both the relative source layout and the override path. Reproducible mode remaps the dependency source to /dragonx-lite-backend-dependency, so release commands do not need a local /home/d/external remap for that dependency.

The target source cleanup and signature metadata boundary are detailed in docs/lite-wallet-backend-source-signature-plan-2026-05-20.md. The relative source layout is now implemented; signature metadata remains read-only artifact inventory to add only after a signing policy exists. Phase 1 artifact production must not sign, upload, publish, or mutate artifacts.

The first Linux build from the relative source layout succeeded without --silentdragonxlitelib-dir: build/lite-backend-relative-linux-b/linux/libsilentdragonxlite.a has SHA-256 8fd6c66ff661e13f768754de69d39e1a15ee55b6fdd530625a6018c867edde10, exported blake3_PW plus all eight required litelib_* symbols, and produced a manifest with portable_dependency_override: false, silentdragonxlitelib_revision: 6a178c8d08d9c1c153fb22759a68177cdb787be7, reproducible: true, and signing_requested: false.

Signature Metadata Plan

The signing policy is defined in docs/lite-wallet-backend-signing-policy-2026-05-22.md. The manifest now always includes a signature_verification object using policy dragonx-lite-backend-signature-policy-v1 while keeping signing_requested: false.

For unsigned local inventory, metadata_provided is false and verification_status is not-provided. When any signature metadata flag is supplied, or when --signature-required is used, the script fails closed unless the sidecar signature exists, the format is accepted, the verifier tool is recorded, a reviewed key fingerprint or certificate identity is present, and the verified artifact SHA-256 matches the artifact bytes recorded in the manifest.

The wallet runtime, LiteBackendArtifactContract, CMake gate, and release readiness scaffolds continue to reject signing requests and do not create signatures. DRAGONX_LITE_BACKEND_REQUIRE_SIGNATURE=ON is available for release builders that want CMake to require verified signature metadata before importing the backend library.

Required Symbols

The exported-symbol inventory must contain the Phase 1 ABI surface required by LiteClientBridgeApi:

  • litelib_wallet_exists
  • litelib_initialize_new
  • litelib_initialize_new_from_phrase
  • litelib_initialize_existing
  • litelib_execute
  • litelib_rust_free_string
  • litelib_check_server_online
  • litelib_shutdown

The inventory may contain extra SDXL symbols such as blake3_PW, but CMake and LiteBackendArtifactContract require the eight symbols above.

CMake Use

When the lite backend is explicitly enabled, CMake now requires the generated symbol inventory:

cmake -S . -B build/lite \
  -DDRAGONX_BUILD_LITE=ON \
  -DDRAGONX_ENABLE_LITE_BACKEND=ON \
  -DDRAGONX_LITE_BACKEND_LIBRARY=build/lite-backend/linux/libsilentdragonxlite.a \
  -DDRAGONX_LITE_BACKEND_SYMBOLS_FILE=build/lite-backend/linux/lite-backend-symbols.txt \
  -DDRAGONX_LITE_BACKEND_MANIFEST=build/lite-backend/linux/lite-backend-artifact-manifest.json \
  -DDRAGONX_LITE_BACKEND_LINK_MODE=imported \
  -DDRAGONX_LITE_BACKEND_ABI=sdxl-c-v1

DRAGONX_LITE_BACKEND_MANIFEST is optional metadata for release traceability, but if supplied it must exist. DRAGONX_LITE_BACKEND_SYMBOLS_FILE is mandatory when DRAGONX_ENABLE_LITE_BACKEND=ON.

DRAGONX_LITE_BACKEND_REQUIRE_SIGNATURE=ON is optional and requires DRAGONX_LITE_BACKEND_MANIFEST. When enabled, CMake requires signature_verification.verification_status to be verified and requires signature_verification.verified_artifact_sha256 to match artifact.sha256 in the manifest before importing the backend library.

DRAGONX_LITE_BACKEND_EXTRA_LIBS is the Phase 1 escape hatch for platform-native or backend-specific static-link dependencies that are discovered by real linker runs. The current contract is to keep it empty until a platform linker proves an additional library or framework is required, then record the exact value used by the release builder.

Linux Verification

On 2026-05-18, the Linux artifact path was verified on this workspace with:

scripts/build-lite-backend-artifact.sh \
  --platform linux \
  --out-dir build/lite-backend-real \
  --builder phase1-real-build

Result:

  • artifact: build/lite-backend-real/linux/libsilentdragonxlite.a
  • size: 126158088 bytes
  • SHA-256: 1a568ac1e90908adeede28e26f478f7b0dce7cf5bd7b9893ce7efa32e842e1ee
  • manifest: build/lite-backend-real/linux/lite-backend-artifact-manifest.json
  • symbols: build/lite-backend-real/linux/lite-backend-symbols.txt

The symbol inventory contains blake3_PW plus all eight required litelib_* symbols. The manifest reports schema dragonx.lite.backend-artifact.v1, ABI sdxl-c-v1, link mode imported, platform linux, kind static-library, builder phase1-real-build, and no missing required symbols.

The generated artifact was then accepted by CMake:

cmake -S . -B build/lite-backend-verify \
  -DDRAGONX_BUILD_LITE=ON \
  -DDRAGONX_ENABLE_LITE_BACKEND=ON \
  -DDRAGONX_LITE_BACKEND_LIBRARY="$PWD/build/lite-backend-real/linux/libsilentdragonxlite.a" \
  -DDRAGONX_LITE_BACKEND_SYMBOLS_FILE="$PWD/build/lite-backend-real/linux/lite-backend-symbols.txt" \
  -DDRAGONX_LITE_BACKEND_MANIFEST="$PWD/build/lite-backend-real/linux/lite-backend-artifact-manifest.json" \
  -DDRAGONX_LITE_BACKEND_LINK_MODE=imported \
  -DDRAGONX_LITE_BACKEND_ABI=sdxl-c-v1

cmake --build build/lite-backend-verify --target ObsidianDragonTests linked successfully against the real static backend artifact, and ./build/lite-backend-verify/bin/ObsidianDragonTests printed Focused service tests passed.

This verification proves the Linux imported-library path, symbol inventory gate, manifest handoff, and focused test link path. It does not execute runtime SDXL wallet/network behavior.

Clean Linux Reproducibility Verification

On 2026-05-18, isolated Linux builds without path remapping produced identical ABI symbol inventories but different static archive bytes because the archive embedded Cargo target-directory paths and LLVM-suffixed internal symbols. Reproducible mode was added for artifact production and then verified with two clean target directories:

scripts/build-lite-backend-artifact.sh \
  --platform linux \
  --reproducible \
  --remap-path-prefix /home/d/external=/dragonx-external \
  --cargo-target-dir build/lite-backend-cargo-repro-a \
  --out-dir build/lite-backend-repro-a \
  --builder phase1-repro-a

scripts/build-lite-backend-artifact.sh \
  --platform linux \
  --reproducible \
  --remap-path-prefix /home/d/external=/dragonx-external \
  --cargo-target-dir build/lite-backend-cargo-repro-b \
  --out-dir build/lite-backend-repro-b \
  --builder phase1-repro-b

Result:

  • artifact: build/lite-backend-repro-a/linux/libsilentdragonxlite.a
  • size: 126147788 bytes
  • SHA-256: 12228f5b895db6cdafb0f643ecb5fbad1a3760b57b7fe98d7084a34644f34622
  • manifest reproducible flag: true
  • second clean artifact SHA-256: 12228f5b895db6cdafb0f643ecb5fbad1a3760b57b7fe98d7084a34644f34622
  • archive byte comparison: identical
  • filtered symbol inventory comparison: identical

The filtered inventory contains blake3_PW plus all eight required litelib_* symbols.

The reproducible Linux artifact was also accepted by CMake in build/lite-backend-repro-verify, linked into ObsidianDragonTests, and ./build/lite-backend-repro-verify/bin/ObsidianDragonTests printed Focused service tests passed.

On 2026-05-19, the portable dependency override path was verified with two clean Linux builds that supplied silentdragonxlitelib through --silentdragonxlitelib-dir instead of relying on the checked-in absolute path:

scripts/build-lite-backend-artifact.sh \
  --platform linux \
  --silentdragonxlitelib-dir /home/d/external/silentdragonxlite-cli/lib \
  --reproducible \
  --cargo-target-dir build/lite-backend-cargo-portable-linux-a \
  --out-dir build/lite-backend-portable-linux-a \
  --builder phase1-portable-linux-a

scripts/build-lite-backend-artifact.sh \
  --platform linux \
  --silentdragonxlitelib-dir /home/d/external/silentdragonxlite-cli/lib \
  --reproducible \
  --cargo-target-dir build/lite-backend-cargo-portable-linux-b \
  --out-dir build/lite-backend-portable-linux-b \
  --builder phase1-portable-linux-b

Result:

  • artifact: build/lite-backend-portable-linux-a/linux/libsilentdragonxlite.a
  • size: 126148614 bytes
  • SHA-256: aaef46b99fdc304be88427852797d6674ac330209b377be5447c1b0805635ea2
  • manifest reproducible flag: true
  • manifest portable dependency override: true
  • silentdragonxlitelib revision: 6a178c8d08d9c1c153fb22759a68177cdb787be7
  • second clean artifact SHA-256: aaef46b99fdc304be88427852797d6674ac330209b377be5447c1b0805635ea2
  • archive byte comparison: identical
  • filtered symbol inventory comparison: identical

The filtered inventory contains blake3_PW plus all eight required litelib_* symbols. This run proves the portable dependency override can replace the previous /home/d/external source-path remap for the dependency itself during Linux artifact production.

The portable Linux artifact was also accepted by CMake in build/lite-backend-portable-verify with DRAGONX_LITE_BACKEND_LIBRARY, DRAGONX_LITE_BACKEND_SYMBOLS_FILE, DRAGONX_LITE_BACKEND_MANIFEST, DRAGONX_LITE_BACKEND_LINK_MODE=imported, and DRAGONX_LITE_BACKEND_ABI=sdxl-c-v1 pointing at build/lite-backend-portable-linux-a/linux/. cmake --build build/lite-backend-portable-verify --target ObsidianDragonTests linked successfully against the portable static backend artifact, and ./build/lite-backend-portable-verify/bin/ObsidianDragonTests printed Focused service tests passed.

On 2026-05-20, the same portable Linux artifact was also linked into the app target without extra backend libraries:

cmake --build build/lite-backend-portable-verify --target ObsidianDragon

Result:

  • binary: build/lite-backend-portable-verify/bin/ObsidianDragonLite
  • size: 100026080 bytes
  • file type: ELF 64-bit LSB PIE x86-64 Linux executable, dynamically linked
  • backend extras: DRAGONX_LITE_BACKEND_EXTRA_LIBS:STRING=
  • dynamic dependencies: normal Linux/system/app dependencies including libcurl.so.4, libsodium.so.23, libOpenGL.so.0, libstdc++.so.6, libssl.so.3, libcrypto.so.3, and standard system libraries

This proves the Linux release app target can link the portable imported backend artifact. The app binary was inspected but not launched.

Windows GNU Verification

On 2026-05-18, this workspace had the x86_64-pc-windows-gnu Rust target and MinGW symbol tools available, including /usr/bin/x86_64-w64-mingw32-gcc and /usr/bin/x86_64-w64-mingw32-nm. The Windows GNU artifact was built with reproducible mode:

scripts/build-lite-backend-artifact.sh \
  --platform windows \
  --rust-target x86_64-pc-windows-gnu \
  --reproducible \
  --remap-path-prefix /home/d/external=/dragonx-external \
  --cargo-target-dir build/lite-backend-cargo-windows \
  --out-dir build/lite-backend-windows \
  --builder phase1-windows-gnu

A second clean Windows GNU build with a separate Cargo target directory produced the same archive bytes and the same filtered symbol inventory.

Result:

  • artifact: build/lite-backend-windows/windows/libsilentdragonxlite.a
  • rust target: x86_64-pc-windows-gnu
  • size: 105565566 bytes
  • SHA-256: bdf1e0175a89560d15232f6430d162c6c009806e048062c124ec40c0744e49be
  • symbol tool: x86_64-w64-mingw32-nm
  • manifest reproducible flag: true
  • archive byte comparison with second clean build: identical
  • filtered symbol inventory comparison with second clean build: identical

The filtered inventory contains blake3_PW plus all eight required litelib_* symbols.

On 2026-05-19, the Windows GNU reproducibility check was repeated with --silentdragonxlitelib-dir so the wrapper dependency path was supplied through portable builder input instead of the checked-in absolute path:

scripts/build-lite-backend-artifact.sh \
  --platform windows \
  --rust-target x86_64-pc-windows-gnu \
  --silentdragonxlitelib-dir /home/d/external/silentdragonxlite-cli/lib \
  --reproducible \
  --cargo-target-dir build/lite-backend-cargo-portable-windows-a \
  --out-dir build/lite-backend-portable-windows-a \
  --builder phase1-portable-windows-a

scripts/build-lite-backend-artifact.sh \
  --platform windows \
  --rust-target x86_64-pc-windows-gnu \
  --silentdragonxlitelib-dir /home/d/external/silentdragonxlite-cli/lib \
  --reproducible \
  --cargo-target-dir build/lite-backend-cargo-portable-windows-b \
  --out-dir build/lite-backend-portable-windows-b \
  --builder phase1-portable-windows-b

Result:

  • artifact: build/lite-backend-portable-windows-a/windows/libsilentdragonxlite.a
  • rust target: x86_64-pc-windows-gnu
  • size: 105565096 bytes
  • SHA-256: 635a9e9bf3254955e63d1e9032e714488fa433cc249c8aabe636b5f18d2d1e3b
  • symbol tool: x86_64-w64-mingw32-nm
  • manifest reproducible flag: true
  • manifest portable dependency override: true
  • silentdragonxlitelib revision: 6a178c8d08d9c1c153fb22759a68177cdb787be7
  • second clean artifact SHA-256: 635a9e9bf3254955e63d1e9032e714488fa433cc249c8aabe636b5f18d2d1e3b
  • archive byte comparison: identical
  • filtered symbol inventory comparison: identical

The filtered inventory contains blake3_PW plus all eight required litelib_* symbols.

On 2026-05-22, the Windows GNU reproducibility check was repeated from the checked-in relative source layout without --silentdragonxlitelib-dir:

scripts/build-lite-backend-artifact.sh \
  --platform windows \
  --rust-target x86_64-pc-windows-gnu \
  --backend-dir external/SilentDragonXLite/lib \
  --reproducible \
  --cargo-target-dir build/lite-backend-relative-target-windows-gnu-a \
  --out-dir build/lite-backend-relative-windows-gnu-a \
  --builder phase1-relative-windows-gnu-a

scripts/build-lite-backend-artifact.sh \
  --platform windows \
  --rust-target x86_64-pc-windows-gnu \
  --backend-dir external/SilentDragonXLite/lib \
  --reproducible \
  --cargo-target-dir build/lite-backend-relative-target-windows-gnu-b \
  --out-dir build/lite-backend-relative-windows-gnu-b \
  --builder phase1-relative-windows-gnu-b

Result:

  • artifact: build/lite-backend-relative-windows-gnu-a/windows/libsilentdragonxlite.a
  • rust target: x86_64-pc-windows-gnu
  • SHA-256: ca7677af58f61de4bd56311e76e32961d977da8fac2a3c5d158c1702f8807439
  • symbol tool: x86_64-w64-mingw32-nm
  • manifest reproducible flag: true
  • manifest portable dependency override: false
  • silentdragonxlitelib revision: 6a178c8d08d9c1c153fb22759a68177cdb787be7
  • second clean artifact SHA-256: ca7677af58f61de4bd56311e76e32961d977da8fac2a3c5d158c1702f8807439
  • archive byte comparison: identical
  • filtered symbol inventory comparison: identical

The filtered inventory contains blake3_PW plus all eight required litelib_* symbols.

On 2026-05-20, the portable Windows GNU artifact was accepted by CMake and linked into the app target from a short build directory:

cmake -S . -B /tmp/od-win-lite-link \
  -DCMAKE_TOOLCHAIN_FILE="$PWD/build/windows/mingw-toolchain.cmake" \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_OBJECT_PATH_MAX=128 \
  -DDRAGONX_USE_SYSTEM_SDL3=OFF \
  -DDRAGONX_BUILD_LITE=ON \
  -DDRAGONX_ENABLE_LITE_BACKEND=ON \
  -DDRAGONX_LITE_BACKEND_LIBRARY="$PWD/build/lite-backend-portable-windows-a/windows/libsilentdragonxlite.a" \
  -DDRAGONX_LITE_BACKEND_SYMBOLS_FILE="$PWD/build/lite-backend-portable-windows-a/windows/lite-backend-symbols.txt" \
  -DDRAGONX_LITE_BACKEND_MANIFEST="$PWD/build/lite-backend-portable-windows-a/windows/lite-backend-artifact-manifest.json" \
  -DDRAGONX_LITE_BACKEND_LINK_MODE=imported \
  -DDRAGONX_LITE_BACKEND_ABI=sdxl-c-v1 \
  '-DDRAGONX_LITE_BACKEND_EXTRA_LIBS=secur32;userenv'

cmake --build /tmp/od-win-lite-link --target ObsidianDragon -j $(nproc)

The first Windows GNU link attempt without extra backend libraries reached the real linker and failed on AcquireCredentialsHandleA, FreeCredentialsHandle, FreeContextBuffer, and GetUserProfileDirectoryW. The successful imported-link value is therefore DRAGONX_LITE_BACKEND_EXTRA_LIBS=secur32;userenv.

Result:

  • binary: /tmp/od-win-lite-link/bin/ObsidianDragonLite.exe
  • size: 106366143 bytes
  • file type: PE32+ executable (GUI) x86-64, for MS Windows
  • imported backend-extra DLL evidence: Secur32.dll and USERENV.dll
  • other imported DLLs observed: ADVAPI32.dll, CRYPT32.dll, D3DCOMPILER_47.dll, GDI32.dll, HID.DLL, IMM32.dll, IPHLPAPI.DLL, KERNEL32.dll, OLEAUT32.dll, PSAPI.DLL, SETUPAPI.dll, SHELL32.dll, USER32.dll, VERSION.dll, WINMM.dll, WS2_32.dll, bcrypt.dll, d3d11.dll, dcomp.dll, dwmapi.dll, msvcrt.dll, and ole32.dll

MinGW also exposed a path-component issue before link: the generated Batch 90 source basename plus .obj.d exceeded the Windows filename component limit. CMake now uses a Windows-only generated wrapper source under generated/short_sources/lite_batch90_receipt_plan.cpp that includes the original source, and the successful build log confirmed generated/short_sources/lite_batch90_receipt_plan.cpp.obj was compiled. The Windows executable was inspected but not run.

On 2026-05-22, the relative-source Windows GNU artifact was accepted by CMake and linked into the app target from /tmp/od-win-relative-link:

cmake -S . -B /tmp/od-win-relative-link \
  -DCMAKE_TOOLCHAIN_FILE="$PWD/build/windows/mingw-toolchain.cmake" \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_OBJECT_PATH_MAX=128 \
  -DDRAGONX_USE_SYSTEM_SDL3=OFF \
  -DDRAGONX_BUILD_LITE=ON \
  -DDRAGONX_ENABLE_LITE_BACKEND=ON \
  -DDRAGONX_LITE_BACKEND_LIBRARY="$PWD/build/lite-backend-relative-windows-gnu-a/windows/libsilentdragonxlite.a" \
  -DDRAGONX_LITE_BACKEND_SYMBOLS_FILE="$PWD/build/lite-backend-relative-windows-gnu-a/windows/lite-backend-symbols.txt" \
  -DDRAGONX_LITE_BACKEND_MANIFEST="$PWD/build/lite-backend-relative-windows-gnu-a/windows/lite-backend-artifact-manifest.json" \
  -DDRAGONX_LITE_BACKEND_LINK_MODE=imported \
  -DDRAGONX_LITE_BACKEND_ABI=sdxl-c-v1 \
  '-DDRAGONX_LITE_BACKEND_EXTRA_LIBS=secur32;userenv'

cmake --build /tmp/od-win-relative-link --target ObsidianDragon -j $(nproc)

Result:

  • binary: /tmp/od-win-relative-link/bin/ObsidianDragonLite.exe
  • file type: PE32+ executable (GUI) x86-64, for MS Windows
  • imported backend-extra DLL evidence: Secur32.dll and USERENV.dll
  • other imported DLLs observed: ADVAPI32.dll, CRYPT32.dll, D3DCOMPILER_47.dll, GDI32.dll, HID.DLL, IMM32.dll, IPHLPAPI.DLL, KERNEL32.dll, OLEAUT32.dll, PSAPI.DLL, SETUPAPI.dll, SHELL32.dll, USER32.dll, VERSION.dll, WINMM.dll, WS2_32.dll, bcrypt.dll, d3d11.dll, dcomp.dll, dwmapi.dll, msvcrt.dll, and ole32.dll

This verifies that the checked-in relative source layout preserves the Windows GNU imported app link contract with the previously proven secur32;userenv backend extras. The executable was inspected but not run.

macOS Verification Status

macOS artifact production was not attempted on 2026-05-18 because this Linux workspace is missing the required Darwin cross-build inputs:

  • no installed Rust Apple target such as x86_64-apple-darwin or aarch64-apple-darwin,
  • no Apple/osxcross compiler wrapper such as o64-clang, x86_64-apple-darwin-clang, or x86_64-apple-darwin20.4-clang,
  • no osxcross-conf,
  • no /opt/osxcross toolchain directory.

macOS remains a Phase 1 platform-artifact verification blocker until a macOS host or configured osxcross builder is available.

The blocker was rechecked on 2026-05-20 from this Linux/WSL workspace. No Apple Rust targets are installed, Xcode is absent, /opt/osxcross is absent, and the Apple/osxcross compiler wrappers o64-clang, x86_64-apple-darwin-clang, x86_64-apple-darwin20.4-clang, aarch64-apple-darwin-clang, and aarch64-apple-darwin20.4-clang are missing. llvm-nm is available for future symbol inventory work, but it is not enough without an Apple target and linker. The artifact script also fails closed for a Linux-hosted macOS request without an explicit Rust target: macOS artifacts require --rust-target when not running on macOS.

The macOS/osxcross builder preflight was repeated later on 2026-05-20 for the Phase 1 macOS verification slice. This shell is still Linux/WSL, has Rust/Cargo 1.63.0, clang, and llvm-nm, but has no installed Apple/Darwin Rust targets, no xcodebuild/xcrun, no otool/lipo, no /opt/osxcross, no osxcross compiler/archive wrappers, and no Apple linker environment variables such as CARGO_TARGET_*APPLE_DARWIN_LINKER, CC_x86_64_apple_darwin, or CC_aarch64_apple_darwin. The attempted artifact command failed closed before producing a macOS artifact:

scripts/build-lite-backend-artifact.sh \
  --platform macos \
  --silentdragonxlitelib-dir /home/d/external/silentdragonxlite-cli/lib \
  --reproducible \
  --cargo-target-dir /tmp/od-lite-macos-cargo-preflight \
  --out-dir /tmp/od-lite-macos-artifact-preflight \
  --builder phase1-macos-preflight

Result: [lite-backend] ERROR: macOS artifacts require --rust-target when not running on macOS. No macOS archive, symbol inventory, manifest, CMake imported-link result, or DRAGONX_LITE_BACKEND_EXTRA_LIBS value was produced on this host.

The macOS/osxcross preflight was repeated on 2026-05-22 from the checked-in relative source layout. This shell still has Rust/Cargo 1.63.0, clang, and llvm-nm, but has no installed Apple/Darwin Rust targets, no xcodebuild/xcrun, no otool/lipo, no /opt/osxcross, no osxcross compiler/archive wrappers, and no Apple linker environment variables. The explicit relative-source artifact attempt reached Cargo with --rust-target x86_64-apple-darwin and failed because the target standard libraries are unavailable:

scripts/build-lite-backend-artifact.sh \
  --platform macos \
  --rust-target x86_64-apple-darwin \
  --backend-dir external/SilentDragonXLite/lib \
  --out-dir /tmp/od-lite-macos-relative-artifact-preflight \
  --cargo-target-dir /tmp/od-lite-macos-relative-cargo-preflight \
  --reproducible \
  --builder phase1-macos-relative-preflight

Result: Cargo exited with code 101 and reported missing compiler_builtins, core, alloc, and std for x86_64-apple-darwin, with the expected rustup target add x86_64-apple-darwin hint. No /tmp/od-lite-macos-relative-artifact-preflight/macos/libsilentdragonxlite.a archive or lite-backend-artifact-manifest.json manifest was produced, so macOS imported-link verification still cannot proceed on this host.

On 2026-05-22, macOS artifact and imported-link verification was deferred by operator request. The builder prerequisites, command shape, and acceptance criteria remain below for a future macOS/osxcross continuation, but current Phase 1 local work should not keep retrying macOS tasks until that deferral is lifted.

macOS Artifact Verification Plan

The macOS verification run must be performed on a macOS host or on a Linux builder with a configured osxcross/Apple SDK toolchain. The repository does not vendor the Apple SDK or handle Apple license acceptance.

Builder prerequisites:

  • Rust Apple target installed, at minimum x86_64-apple-darwin; add aarch64-apple-darwin when Apple Silicon artifacts are in scope.
  • Apple linker/compiler wrappers available, for example clang on macOS or osxcross tools such as o64-clang, x86_64-apple-darwin-clang, and matching ar/ranlib tools.
  • llvm-nm or a Darwin-capable nm available for static archive symbol inventory.
  • The checked-in relative source layout under external/SilentDragonXLite/lib and external/SilentDragonXLite/silentdragonxlite-cli; use --silentdragonxlitelib-dir only for comparison against an external maintained checkout.
  • Isolated Cargo target directories for two clean reproducibility runs.

Command shape for an Intel macOS artifact:

scripts/build-lite-backend-artifact.sh \
  --platform macos \
  --rust-target x86_64-apple-darwin \
  --backend-dir external/SilentDragonXLite/lib \
  --reproducible \
  --cargo-target-dir build/lite-backend-relative-target-macos-x64-a \
  --out-dir build/lite-backend-relative-macos-x64-a \
  --builder phase1-relative-macos-x64-a

Repeat the same command with a second clean Cargo target and output directory, then compare the archive SHA-256 values and filtered lite-backend-symbols.txt files. For osxcross builders, set the target linker/compiler environment before running the same script command, for example CARGO_TARGET_X86_64_APPLE_DARWIN_LINKER=o64-clang and CC_x86_64_apple_darwin=o64-clang.

macOS acceptance criteria:

  • The script generates a dragonx.lite.backend-artifact.v1 manifest with platform macos, ABI sdxl-c-v1, link mode imported, and reproducible provenance for build runs that use --reproducible.
  • lite-backend-symbols.txt contains blake3_PW if exported plus all eight required litelib_* symbols.
  • Two clean macOS builds are byte-identical, or any remaining nondeterminism is documented with identical required-symbol inventories and a follow-up owner.
  • On a macOS builder capable of linking the wallet tests, CMake accepts the generated artifact through DRAGONX_LITE_BACKEND_LIBRARY, DRAGONX_LITE_BACKEND_SYMBOLS_FILE, DRAGONX_LITE_BACKEND_MANIFEST, DRAGONX_LITE_BACKEND_LINK_MODE=imported, and DRAGONX_LITE_BACKEND_ABI=sdxl-c-v1, then ObsidianDragonTests links and prints Focused service tests passed.
  • Cross-only osxcross runs that cannot execute the test binary must still prove Cargo build success, Darwin symbol inventory, manifest generation, and CMake configure/link success where the toolchain permits it.

CMake links the imported dragonx_lite_backend target into both ObsidianDragon and ObsidianDragonTests only when DRAGONX_ENABLE_LITE_BACKEND=ON and the artifact gate has passed. The same link sites append DRAGONX_LITE_BACKEND_EXTRA_LIBS, so platform release builders can add verified backend-native dependencies without changing full-node defaults or enabling runtime dynamic loading.

Current planning status:

  • Linux: the portable static backend artifact linked into both ObsidianDragonTests and the ObsidianDragon app target on this workspace with DRAGONX_LITE_BACKEND_EXTRA_LIBS empty. The app target produced build/lite-backend-portable-verify/bin/ObsidianDragonLite and was inspected without launch.
  • Windows GNU: artifact production, symbol inventory, clean reproducibility, CMake configure, and app imported-link verification are complete for both the portable override artifact and the checked-in relative source artifact on this host. The first no-extra portable link proved missing secur32/userenv APIs; the successful release-builder value remains DRAGONX_LITE_BACKEND_EXTRA_LIBS=secur32;userenv, producing /tmp/od-win-lite-link/bin/ObsidianDragonLite.exe for the portable artifact and /tmp/od-win-relative-link/bin/ObsidianDragonLite.exe for the relative artifact without running either executable.
  • macOS: artifact and link verification are deferred by operator request after the blocked 2026-05-22 relative-source preflight. The first resumed macOS linker pass should use the existing local libs/libsodium-mac/libs/libsodium search path plus the app's platform frameworks, then add backend-specific libraries or frameworks through DRAGONX_LITE_BACKEND_EXTRA_LIBS only when the Darwin linker proves they are needed.

Example shape for a platform builder after it has identified real extra dependencies:

cmake -S . -B build/lite-platform-verify \
  -DDRAGONX_BUILD_LITE=ON \
  -DDRAGONX_ENABLE_LITE_BACKEND=ON \
  -DDRAGONX_LITE_BACKEND_LIBRARY=/path/to/libsilentdragonxlite.a \
  -DDRAGONX_LITE_BACKEND_SYMBOLS_FILE=/path/to/lite-backend-symbols.txt \
  -DDRAGONX_LITE_BACKEND_MANIFEST=/path/to/lite-backend-artifact-manifest.json \
  -DDRAGONX_LITE_BACKEND_LINK_MODE=imported \
  -DDRAGONX_LITE_BACKEND_ABI=sdxl-c-v1 \
  -DDRAGONX_LITE_BACKEND_EXTRA_LIBS="<verified-extra-lib-1>;<verified-extra-lib-2>"

If no backend-specific extras are needed, omit DRAGONX_LITE_BACKEND_EXTRA_LIBS and keep the manifest plus symbol inventory as the evidence of the artifact that was linked.

Guardrails

The script performs build and read-only artifact inspection only. It does not:

  • load dynamic libraries,
  • resolve runtime symbols,
  • call SDXL or bridge APIs,
  • check servers,
  • create/open/restore wallets,
  • start sync or poll syncstatus,
  • mutate WalletState,
  • persist wallet files,
  • sign, upload, or publish artifacts.