- 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>
97 lines
11 KiB
Markdown
97 lines
11 KiB
Markdown
# 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. |