nim-chat-poc/cleanup/05b-weak-types.md

39 lines
3.1 KiB
Markdown
Raw Normal View History

# Cleanup 05B — Weak types re-evaluation
Follow-up to `05-weak-types.md`. Cleanup Agent 05's verdict was "everything justified, only the doc-comment is fixable". Re-examination found one site Agent 05 dismissed too quickly.
## Push-back assessment
| Site Agent 05 dismissed | New verdict | Why |
|---|---|---|
| `cast[pointer](lezGm)` at the three call sites | **FIXABLE** | Agent 05 framed this as "consequence of the global being `pointer`". Correct premise, wrong conclusion. The PUBLIC SURFACE of `setGroupManagerRef` doesn't need to be `pointer` — it can take the concrete `OnchainLEZGroupManager` and erase to `pointer` internally for the lock-protected global. Removes 3 `cast[pointer]` from caller sites with no semantic change. |
| `cast[GroupManager](gm)` in `setRlnIdentity` | **FIXABLE** | Agent 05 left this alone. The cast was to the *base* `GroupManager` type even though every caller stashes an `OnchainLEZGroupManager`. Narrowing the cast target to the concrete subtype is type-honest and free. |
| `rlnGroupManager: pointer` global itself | **AGREE, keep `pointer`** | Cross-thread lock-protected global; Nim `ref` storage there risks GC interference. Agent 05 was right. |
| `cast[ptr FetchResult](userData)` | **AGREE, keep** | C-callback userData pattern. |
| `cast[cstring](allocShared0(...))` | **AGREE, keep** | `allocShared0` returns `pointer`; the `cstring` cast is the typed view. |
| `pointer` in `RlnFetchCallback` / `RlnFetcherFunc` (`callbackData`, `fetcherData`) | **AGREE, keep** | `{.cdecl.}` callbacks invoked from C. |
| Rust `*const u8` in `lez-rln-ffi/src/lib.rs` | **AGREE, keep** | C ABI surface. |
## Applied
- `vendor/nwaku/waku/waku_mix/logos_core_client.nim`:
- `setGroupManagerRef*(gm: pointer)``setGroupManagerRef*(lezGm: OnchainLEZGroupManager)`. Internal `cast[pointer](lezGm)` does the erasure for the cross-thread global.
- `setRlnIdentity` casts back to `OnchainLEZGroupManager` (the concrete subtype that every caller actually stashes) instead of `GroupManager`.
- Comment on `rlnGroupManager: pointer` updated accordingly (mentions `OnchainLEZGroupManager`).
- `vendor/nwaku/waku/factory/node_factory.nim`: caller drops `cast[pointer](lezGm)` — passes the ref directly.
- `src/chat/delivery/waku_client.nim`: same caller-site cast dropped.
- Mirrored into the loose `logos-delivery` checkout (byte-identical).
Builds: both `liblogoschat` and `liblogosdelivery` clean.
Local sim: ALL 15 PASS.
### Commit SHAs
- vendor/nwaku: `618ce267`
- vendor/logos-lez-rln/logos-delivery (loose): `d960a564`
- outer logos-chat: `fce56b3`
## Deferred
- The internal `cast[pointer](lezGm)` inside `setGroupManagerRef` and the `cast[OnchainLEZGroupManager](gm)` inside `setRlnIdentity` are now the only two casts in this path. Both are mandated by the cross-thread global pattern. Wrapping them in a `distinct pointer` handle was considered and rejected: a `distinct pointer` would buy zero safety here (single writer + single reader inside the same module, both casts justified by the cross-thread storage contract), while adding a new type that has to be threaded through callers.