You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(abi): make the probe-handle lifecycle real and correct the Idris wrappers
The proven-ABI story was connected to nothing: gossamer_gsa_probe returned
a bare result code (never a handle), gossamer_gsa_close_handle was a no-op
(_ = handle;), and every Foreign.idr wrapper assumed negative error codes
the Zig side never emits. So the Idris linear-type guarantees
(AlreadyConsumed/DoubleFree) had no runtime counterpart.
Zig side (main.zig, probe.zig, abi_serde.zig):
- GsaHandle now issues monotonic handle ids (>= FIRST_HANDLE_ID = 1000,
disjoint from the 0-17 result-code space so a success value can never be
read as an error code).
- gossamer_gsa_probe returns the handle id; gossamer_gsa_close_handle
validates it, frees the binding, and reports double_free on a repeat
close and not_found for a stray id, via a bounded tombstone ring.
- gossamer_gsa_apply_config validates the handle (already_consumed if the
handle was closed) instead of ignoring it.
- Two new tests cover open/use/close/double-close/unknown and the bounded
tombstone ring.
Idris side (Foreign.idr):
- New resultOf/parseResultCode drop the bogus negation: a code of 0 is Ok,
1-17 is that GsaResult (Zig never negates — grep-verified).
- probe classifies its return by magnitude (>= firstHandleId = handle).
- prim__serverAction and prim__getLogs retyped from Int to String to match
the real C signatures (both return char*, not codes/arrays); wrappers
updated (serverAction returns the JSON string, getLogs splits lines).
- fingerprint now consumes the handle it produces (no leak); storeOctad,
addProfile, applyConfig, checkHealth reworked to honest behaviour with
scope notes where an Idris-side struct emitter is the documented follow-up.
Ephapax (Bridge.eph): probe success checks widened to >= 1000; code-returning
FFI checks tightened to != 0 to match the positive-code convention.
CI: new abi-contract.yml regenerates both expected tables and fails on drift,
runs the comptime cross-check via zig build, and type-checks the Idris2
package (was never compiled in CI — the reason this drift shipped).
cross-platform.yml now also runs the smoke and property suites.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TaWWedv6VQqeZaPvc94keN
let prov = "{\"event_type\":\"nexus_stage\",\"actor\":\"gsa-gui\",\"description\":\"SteamCMD stage for " ++ profile_id ++ " on " ++ target_host ++ "\"}" in
0 commit comments