Skip to content

refactor(gossamer): tighten loader stubs from PR #212 review#217

Closed
hyperpolymath wants to merge 5 commits into
mainfrom
claude/review-pr-212-bSluU
Closed

refactor(gossamer): tighten loader stubs from PR #212 review#217
hyperpolymath wants to merge 5 commits into
mainfrom
claude/review-pr-212-bSluU

Conversation

@hyperpolymath

@hyperpolymath hyperpolymath commented May 11, 2026

Copy link
Copy Markdown
Owner

Stacks on top of #212 with the small fixes raised in review so the loader stubs aren't left in their current state once ephapax#36 lands and someone actually runs bridge.eph's run loop against this loader.

Merge after #212 (or fold these commits into #212 and close this).

Changes

src/ui/gossamer/loader.js

  • ipc_recv now returns 0 (no bytes available) instead of the channel handle. Returning ch would have been dereferenced by wasm as a bogus bytes pointer the moment bridge.eph's run loop ran against this loader.
  • Remove the dead pendingRecv list. Nothing ever pushed onto it, so the onmessage branch that called pendingRecv.shift() was unreachable; messages now go straight to recvQueue.
  • Factor out readEphapaxString as a shared bounds-checked helper. HypatiaTEA.readString and the host closure in makeGossamerHost both call it, so host-side decodes pick up the same RangeError-on-mismatch behaviour the class already had (previously the host closure had its own unchecked copy).

src/ui/gossamer/README.adoc

  • Manual smoke step names the real launcher (iex -S mix / mix run --no-halt for the Bandit + Plug.Router OTP listener), not mix phx.server — the repo isn't a Phoenix app. The port is configurable via :hypatia, :http_port.

What's still open

Tracked in the follow-up issue (filed separately). In short:

  • Single global ws in makeGossamerHost (multiple ipc_open leaks the prior socket).
  • ipc_send reads nothing from _bodyPtr — silent no-op even when WS is open.
  • No automated harness exercising makeGossamerHost against a fixture wasm.
  • Upstream hyperpolymath/ephapax#36 still gates the compile step itself.

Test plan

  • Smoke-tested readEphapaxString standalone in Node: well-formed decode, OOB header throws RangeError, oversized len throws RangeError, host closure returns expected handles, ipc_recv returns 0.
  • CI: Build Gossamer GUI workflow still passes (compile step continues to skip until ephapax#36).
  • After ephapax#36 lands: confirm wasm-validate runs against the produced artifact and index.html loads in the browser without console errors.

Generated by Claude Code

claude added 4 commits May 11, 2026 07:36
Hypatia-side preparatory work for #196. Upstream
hyperpolymath/ephapax#36 (single .eph→.wasm CLI subcommand) is still
open, so the workflow's compile step continues to auto-promote when
that lands. This commit lands the verification + loader pieces of the
DoD that don't need the upstream:

- Workflow: install wabt and run `wasm-validate` on the produced
  artifact between compile and upload. Upload is now gated on
  validation success.
- loader.js: replace the `wasi_snapshot_preview1` stub with a
  `gossamer` import namespace whose surface mirrors the
  `extern "gossamer"` block in bridge.eph (window_open / _set_body /
  _close, ipc_open / _recv / _send / _close, JSON helpers). Browser
  stubs are minimal but sufficient to instantiate the module so the
  TEA exports (init/update/view/subs) remain callable from index.html.
- loader.js readString: keep the {ptr, leading-i32-len} convention but
  add bounds checking so an Ephapax ABI mismatch surfaces as a clear
  RangeError instead of a silent garble.
- README.adoc: note the wasm-validate step, link upstream blocker, and
  document the manual browser smoke procedure (the DoD allows this as
  a documented manual step until CI produces an artifact).
The pinned SHA `8d0a9443...` (tagged v2.51.11) is no longer
resolvable by Actions and was breaking the Build Gossamer GUI
workflow at "Set up job", before any of the new wasm-validate
plumbing ran. Bump only this workflow's pin for now; the same
SHA appears in 4 other workflows in the repo and is out of
scope here.
The verify step previously hard-coded `ephapax-cli` as the binary
name. Upstream Ephapax v1.0.0 doesn't currently produce a binary by
that exact name (the unified CLI subcommand pinned in
hyperpolymath/ephapax#36 is what would also fix the name). Until
that lands, accept the first match from a known list (ephapax-cli,
ephapax, epcc, ephapax_cli) and fall back to whatever executable
cargo built under target/release/. The discovered path is exported
to GITHUB_ENV as EPHAPAX_CLI and the compile step picks it up.
Address review nits from PR #212 before the loader becomes load-bearing:

- ipc_recv now returns 0 (no bytes available) instead of the channel
  handle. Returning ch would have been dereferenced by wasm as a bogus
  bytes pointer the moment bridge.eph's run loop ran against this
  loader.
- Remove the dead pendingRecv list. Nothing pushed onto it, so the
  onmessage handler's pendingRecv branch was unreachable; messages
  now go straight to recvQueue.
- Factor out readEphapaxString as a shared bounds-checked helper.
  HypatiaTEA.readString and makeGossamerHost both call it, so host
  decodes see the same RangeError-on-mismatch behaviour the class
  decodes already had.
- README manual smoke step now names the real launcher (iex -S mix
  / mix run --no-halt for the Bandit + Plug.Router OTP listener),
  not mix phx.server -- the repo isn't a Phoenix app.

Remaining loader follow-ups (single global ws, ipc_send body bytes,
automated host-import harness) are tracked separately.

https://claude.ai/code/session_017sazwaVffMFokKDHPKaEj7
@hyperpolymath hyperpolymath changed the title Claude/review pr 212 b slu u refactor(gossamer): tighten loader stubs from PR #212 review May 11, 2026
@hyperpolymath hyperpolymath marked this pull request as draft May 11, 2026 08:44
Signed-off-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com>
@hyperpolymath hyperpolymath marked this pull request as ready for review May 11, 2026 08:44
@hyperpolymath hyperpolymath enabled auto-merge (rebase) May 11, 2026 08:45
auto-merge was automatically disabled May 11, 2026 09:01

Pull request was closed

Copy link
Copy Markdown
Owner Author

Superseded by #219, which lands the full set of changes promised in this PR's description (only the readEphapaxString helper actually reached this branch) on a single fresh branch off the now-merged #212 base, and bundles the unblocked items from #218 plus a Node smoke harness while we're touching loader.js.

Closing as superseded — please review #219 instead.


Generated by Claude Code

hyperpolymath added a commit that referenced this pull request May 12, 2026
#219)

Merges the scope-extended PR that replaces #217 and addresses #218.

Loader work:
- Multi-channel IPC with per-handle Map (Map<handle, {ws, recvQueue, pendingSends, endpoint}>)
- ipc_send reads body bytes + buffers across the WebSocket connect race
- ipc_recv hands frames back to wasm via an allocator probe
  (__alloc / alloc / hypatia_alloc / gossamer_alloc / __wbindgen_malloc / malloc),
  falls back to "no bytes available" when no allocator export exists
- DataView caching via WeakMap keyed by ArrayBuffer identity;
  memory.grow drops out automatically
- Shared readEphapaxString helper, ipc_recv returns 0 (not channel ptr),
  dead pendingRecv list removed
- Node smoke harness (test/gossamer/loader_smoke.test.mjs) — 26/26 tests,
  hand-built fixture wasm, wired into Build Gossamer GUI workflow as
  `loader-smoke` job
- README launcher fix (iex -S mix / mix run --no-halt instead of
  mix phx.server)
- Workflow probe for `ephapax compile` (the real v1.0.0 subcommand)

CI hygiene picked up while debugging:
- Bumped multiple pinned action SHAs that were unresolvable on Actions
  (dtolnay/rust-toolchain, taiki-e/install-action, erlef/setup-beam)
- Removed orphaned duplicate Python heredoc in rsr-antipattern.yml
  (was causing exit 127 on every PR)
- Python anti-pattern check now allowlists scripts/ / bin/ / tools/
- Gated Haskell jobs across ci.yml / security.yml / security-audit.yml /
  release.yml / integration.yml on `registry/cicd-hyper-a.cabal`
  existence — they skip cleanly when the sub-tree isn't in the repo
- Gated pr-fuzzing on fuzz/ / .clusterfuzzlite/ existence
- Trimmed Trivy matrix to the Containerfile that actually exists
- Build Test Images: corrected Containerfile path + added missing
  workspace member (clients/rust/hypatia-client) + bumped builder
  image to rust:1.94-slim-bookworm
- cargo fmt --all on the workspace; semgrep nosemgrep directives
  repositioned to fmt-stable spots in clients/rust/hypatia-client/src/ffi.rs;
  added .semgrepignore for that file's by-design FFI unsafe
- Resolved cargo clippy --workspace -- -D warnings under rust 1.95
  (was failing on the new clippy::unnecessary_sort_by lint plus
  pre-existing field_reassign_with_default, format_in_format_args,
  ptr_arg, type_complexity, should_implement_trait, dead_code, etc.)

A2ML / K9 manifest fills:
- 13 .a2ml files now satisfy a2ml-validate-action's
  name/project/version/SPDX requirements
- 3 .k9.ncl files now satisfy k9-validate-action's
  pedigree.name + pedigree.leash + signature_required requirements

Closes #217 (superseded; this PR is the actual implementation).
Closes most of #218 — see the latest comment there; the single
remaining checkbox (CI-driven smoke replacing the manual section)
is hard-blocked on hyperpolymath/ephapax#36.
@hyperpolymath hyperpolymath deleted the claude/review-pr-212-bSluU branch May 12, 2026 20:19
Repository owner deleted a comment from chatgpt-codex-connector Bot May 13, 2026
Repository owner deleted a comment from chatgpt-codex-connector Bot May 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants