Files
ObsidianDragon/docs/lite-wallet-backend-artifact-link-contract-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

11 KiB

Lite Wallet Backend Artifact Link Contract - 2026-05-18

Phase 1 Decision

The first production backend path is an explicitly configured imported CMake library. Runtime dynamic loading remains a Phase 2 bridge-runtime-owner task. External executable bridge mode is not part of the Phase 1 production contract.

The default build remains unchanged: DRAGONX_ENABLE_LITE_BACKEND=OFF. Full-node builds do not require Rust, SDXL, or lite backend artifacts.

CMake Gate

The enabled lite backend path requires:

  • DRAGONX_BUILD_LITE=ON
  • DRAGONX_ENABLE_LITE_BACKEND=ON
  • DRAGONX_LITE_BACKEND_LIBRARY=<path to static or shared library>
  • DRAGONX_LITE_BACKEND_SYMBOLS_FILE=<path to generated symbol inventory>
  • DRAGONX_LITE_BACKEND_LINK_MODE=imported
  • DRAGONX_LITE_BACKEND_ABI=sdxl-c-v1
  • DRAGONX_LITE_BACKEND_REQUIRE_SIGNATURE=ON only when a release builder wants CMake to require verified signature metadata in the manifest
  • DRAGONX_LITE_BACKEND_EXTRA_LIBS=<verified platform extras> only when a platform linker proves additional backend-native dependencies are required

When those values are accepted, CMake imports the library as dragonx_lite_backend and links it into ObsidianDragonLite. No runtime dynamic loading is attempted by this Phase 1 contract.

DRAGONX_LITE_BACKEND_MANIFEST=<path to generated artifact manifest> is optional, but if supplied it must exist. The symbol inventory is mandatory so enabled backend builds fail closed before link-time or runtime when the artifact does not expose the expected C ABI. If DRAGONX_LITE_BACKEND_REQUIRE_SIGNATURE=ON, the manifest becomes mandatory and CMake rejects it unless the read-only signature metadata is verified and matches the artifact SHA-256.

DRAGONX_LITE_BACKEND_EXTRA_LIBS is intentionally a cache string instead of hardcoded platform guesses. Release builders should keep it empty for platforms that link successfully with the imported artifact and existing app/system libraries, and should document any non-empty value next to the platform artifact manifest that required it.

Artifact Production

scripts/build-lite-backend-artifact.sh builds or inventories the SDXL-compatible backend artifact and writes:

  • the copied backend library artifact,
  • lite-backend-symbols.txt, one exported symbol per line,
  • lite-backend-artifact-manifest.json, including SHA-256, byte size, source revisions, builder label, ABI, platform, and provenance facts.

See docs/lite-wallet-backend-artifact-production-2026-05-18.md for platform commands and the no-build inventory mode.

The relative backend source layout and signature metadata boundary are recorded in docs/lite-wallet-backend-source-signature-plan-2026-05-20.md. The maintained dependency source is now vendored under external/SilentDragonXLite/silentdragonxlite-cli, and the wrapper uses silentdragonxlitelib = { path = "../silentdragonxlite-cli/lib" }. The portable override remains available for comparison against an external checkout, but release verification should move to the relative source layout. Signature metadata is read-only verification inventory under docs/lite-wallet-backend-signing-policy-2026-05-22.md; signing itself stays outside CMake, runtime code, and Phase 1 artifact production.

Platform Artifact Status

As of 2026-05-22, artifact production has moved past local Linux proof into clean-builder reproducibility and imported-link checks:

  • Linux static artifact production is reproducible when built with --reproducible, an isolated --cargo-target-dir, and a remap for the current external silentdragonxlitelib path. Two clean Linux builds produced byte-identical archives with SHA-256 12228f5b895db6cdafb0f643ecb5fbad1a3760b57b7fe98d7084a34644f34622.
  • Windows GNU static artifact production is reproducible on this host with x86_64-pc-windows-gnu and MinGW tools. Two clean Windows builds produced byte-identical archives with SHA-256 bdf1e0175a89560d15232f6430d162c6c009806e048062c124ec40c0744e49be.
  • The artifact script now has a portable dependency override through --silentdragonxlitelib-dir, which prepares a generated backend wrapper under the output directory and records the override in artifact provenance instead of relying on the local absolute dependency path in the checked-in wrapper manifest.
  • Clean Linux and Windows GNU builds using --silentdragonxlitelib-dir /home/d/external/silentdragonxlite-cli/lib are reproducible. The portable Linux archive SHA-256 is aaef46b99fdc304be88427852797d6674ac330209b377be5447c1b0805635ea2; the portable Windows GNU archive SHA-256 is 635a9e9bf3254955e63d1e9032e714488fa433cc249c8aabe636b5f18d2d1e3b.
  • The checked-in backend source now carries the relative silentdragonxlitelib layout. A Linux build without --silentdragonxlitelib-dir produced build/lite-backend-relative-linux-b/linux/libsilentdragonxlite.a with SHA-256 8fd6c66ff661e13f768754de69d39e1a15ee55b6fdd530625a6018c867edde10; its manifest records portable_dependency_override: false, silentdragonxlitelib_revision: 6a178c8d08d9c1c153fb22759a68177cdb787be7, reproducible: true, and signing_requested: false.
  • Windows GNU clean builds from the checked-in relative source layout are reproducible. Two clean builds produced byte-identical build/lite-backend-relative-windows-gnu-a/windows/libsilentdragonxlite.a and build/lite-backend-relative-windows-gnu-b/windows/libsilentdragonxlite.a archives with SHA-256 ca7677af58f61de4bd56311e76e32961d977da8fac2a3c5d158c1702f8807439; both manifests record portable_dependency_override: false, silentdragonxlitelib_revision: 6a178c8d08d9c1c153fb22759a68177cdb787be7, rust_target: x86_64-pc-windows-gnu, reproducible: true, and signing_requested: false.
  • The portable Linux artifact was accepted by CMake in build/lite-backend-portable-verify, linked into ObsidianDragonTests, and the focused suite printed Focused service tests passed. The same artifact also linked into the ObsidianDragon app target with DRAGONX_LITE_BACKEND_EXTRA_LIBS empty, producing build/lite-backend-portable-verify/bin/ObsidianDragonLite for inspection without launch.
  • Windows GNU imported app linking is verified for the portable artifact from /tmp/od-win-lite-link. The first no-extra link proved missing AcquireCredentialsHandleA, FreeCredentialsHandle, FreeContextBuffer, and GetUserProfileDirectoryW; the successful builder value is DRAGONX_LITE_BACKEND_EXTRA_LIBS=secur32;userenv, producing /tmp/od-win-lite-link/bin/ObsidianDragonLite.exe as a PE32+ GUI x86-64 Windows executable. The executable was inspected but not run.
  • Windows GNU imported app linking is also verified for the relative-source artifact from /tmp/od-win-relative-link with the same DRAGONX_LITE_BACKEND_EXTRA_LIBS=secur32;userenv value, producing /tmp/od-win-relative-link/bin/ObsidianDragonLite.exe as a PE32+ GUI x86-64 Windows executable. The import table includes Secur32.dll and USERENV.dll; the executable was inspected but not run.
  • The Windows GNU link run also proved the need for a Windows-only short CMake wrapper for the overlong Batch 90 generated source basename, because MinGW dependency files append .obj.d and exceed the filename component limit otherwise.
  • macOS artifact production is blocked on this Linux workspace until an Apple Rust target and Apple/osxcross linker toolchain are available, and is deferred for now by operator request. The blocker was rechecked twice on 2026-05-20 and again on 2026-05-22; the host still has no installed Apple Rust targets, no Xcode, no /opt/osxcross, no Apple/osxcross compiler wrappers, and no Apple linker environment variables. The 2026-05-22 checked-in relative-source attempt with --rust-target x86_64-apple-darwin reached Cargo and failed with missing compiler_builtins, core, alloc, and std for that target. No macOS archive, symbol inventory, manifest, imported-link result, or extra-link-library value has been produced yet. The macOS builder prerequisites, command shape, acceptance criteria, and platform link-library planning notes remain recorded in the artifact production guide for a future continuation.
  • Platform native link libraries are not being guessed in CMake. Linux test/app linking currently succeeds with DRAGONX_LITE_BACKEND_EXTRA_LIBS empty, Windows GNU app linking succeeds with secur32;userenv, and macOS imported-link verification must record any actual extra backend-specific libraries after Darwin linker proof.

Both verified platform artifacts expose blake3_PW plus all eight required litelib_* symbols. These checks still do not load, resolve, or call the backend at runtime.

Required C ABI

The artifact must export these C symbols, matching LiteClientBridgeApi:

Symbol Purpose Return ownership
litelib_wallet_exists Check wallet existence for a chain caller does not free
litelib_initialize_new Create a new wallet returned string must be freed
litelib_initialize_new_from_phrase Restore wallet from seed phrase returned string must be freed
litelib_initialize_existing Open an existing wallet returned string must be freed
litelib_execute Execute SDXL command strings such as sync, syncstatus, balance, list, send, import, export, save, shield, and encryption commands returned string must be freed
litelib_rust_free_string Free strings returned by the Rust backend cleanup function
litelib_check_server_online Check lite server availability caller does not free
litelib_shutdown Shut down backend resources no returned value

The supported ABI version label is sdxl-c-v1.

Contract Helper

src/wallet/lite_backend_artifact_contract.h/.cpp adds LiteBackendArtifactContract. It validates caller-supplied artifact metadata and exported-symbol inventory, then produces a LiteBackendArtifactResolverInput for the existing read-only resolver.

The helper verifies:

  • contract owner and read-only gate are ready,
  • link mode is the Phase 1 imported-library path,
  • artifact path is configured,
  • artifact kind is static or shared library,
  • ABI version is sdxl-c-v1,
  • required signature metadata is complete and verified when release policy requires it,
  • symbol inventory owner is ready,
  • all required C ABI symbols are present,
  • no artifact mutation, dynamic library load/unload, symbol resolution, SDXL call, bridge call, server check, lifecycle, sync, worker, WalletState, persistence, upload, signing, or publication action is requested.

The helper never loads the artifact, resolves symbols, calls the bridge, calls SDXL, or enables runtime activation.

Remaining Phase 1 Work

  • macOS artifact and imported-link verification is deferred for now by operator request; when resumed on a macOS host or configured osxcross builder, record any proven DRAGONX_LITE_BACKEND_EXTRA_LIBS values next to the artifact manifests.
  • Read-only signature metadata capture and the optional CMake signature gate are implemented; signing itself remains outside wallet runtime code. Capture real signed-artifact evidence only when a release builder provides sidecar signatures.