Delete the Glove-side synthetic wallet bridge, JSON codec, managed
session, and Pi status adapter plus their fuzz corpus; wallet
observation becomes a Sage-owned capability and Glove stays
harness-neutral.
GLM complementary review remediation on the wallet stack:
- The Pi status adapter content string now reflects the structured
connected flag ("Wallet is not connected.") instead of an
unconditional "Wallet status is available." that contradicted
connected:false; bound by a new REQUIRE on the disconnected path.
- The wallet_status_json fuzzer clock now advances its monotonic
component from fuzz input, so fuzzed frames traverse the deeper
revalidation ladder and deadline paths instead of a single fixed-
authority success path.
- docs/architecture.md: documented the one-strike authority teardown
contract (no retry/resync by the bridge) and the ABA generation-
reuse defense living in authority contracts, gated on adversarial
authority tests before any live composition.
Validation (umask 0022): dev CTest 79/79, ASan/UBSan 79/79,
TSan 79/79; wallet_status_json fuzzer 10,000 units fuzz_exit=0;
clang-format clean; git diff --check clean.
Wallet status bridge: strict typed JSON wire, bounded channel, and
no-mutation status surface. Includes the wallet_status_json fuzzer
with a seed corpus (duplicate method keys, escaped duplicates,
malformed surrogates, nested duplicates, out-of-range requests,
unknown fields, and valid request/response shapes) and the
wallet_status_bridge unit suite.
Layer 3 of the reviewed Glove wallet-status stack; status-only,
disabled by default, and no capability advertisement.
Validation: dev CTest, ASan/UBSan, TSan, and libFuzzer 10,000 units
on the final stacked tree (see workflow184 layer records).
Merge PR #23 head 4097a21adb (Velinus's
"Make Apple resource sampling lifecycle safe") into the Layer-2
integration branch, preserving all contributor commits unchanged.
Retained proven fixes from 4097a21:
- Sampler creation moves into start_finalizer() so a sampler
std::system_error is reported synchronously to the caller. In
ca8600a the sampler was constructed inside finalize() after the
caller had treated startup as successful; the failure path
published an error without attach reaping, container deletion, or
durable mark_managed_failed, and set finished_ so stop() became a
no-op while attach/container survived.
Repairs retained beyond the contributor head, each bound to a
demonstrated failure:
- std::jthread + deterministic stop_token handles the partial-start
case where sampler construction succeeds but finalizer launch
fails (regression: tests/control/apple_container_unavailable_test
and the start_sampler_then_finalizer seam used by production).
- Restored hard-disabled Apple boundary: lifecycle_operational()
false, receipt schema 0, disk enforcement unavailable, empty
managed runtime advertisement, and public method denial before
any side effect. The current PR #23 head crossed the reviewed
activation boundary (schema 0 -> 1, filesystem_quota advertised,
lifecycle constructed-state true) without live-validation.
- glaze parsing hardened: strict_json_options now sets
null_terminated=false; non-NUL-terminated string_views fed
parse_apple_container_stats and duplicate_key_guard caused a
heap-buffer-overflow read in glz::skip_ws (ASan crash input
[{"id":"aanumProcesses" reproduced deterministically; seed corpus
fuzz/corpus/apple_container_stats/truncated-object.json added).
- Sage bundle projection admission hardening (Layer-1 2bba117) and
its test coverage carried through the merge.
Validation (umask 0022):
- Dev CTest 76/76; ASan/UBSan 76/76; TSan 76/76.
- libFuzzer 10,000 units each: library_bundle, session_plan,
apple_container_stats (LLVM 22, ASan/UBSan), all fuzz_exit=0.
- clang-format clean on changed TUs; git diff --check clean.