Skip to content

feat(ffi,core): shell spawn/kill + fs mkdir_p/copy_file with .eph wrappers#26

Merged
hyperpolymath merged 1 commit into
mainfrom
feat/cli-ffi-shell-spawn-fs-mkdir
May 20, 2026
Merged

feat(ffi,core): shell spawn/kill + fs mkdir_p/copy_file with .eph wrappers#26
hyperpolymath merged 1 commit into
mainfrom
feat/cli-ffi-shell-spawn-fs-mkdir

Conversation

@hyperpolymath
Copy link
Copy Markdown
Owner

Summary

Adds four capability-gated FFI exports the upcoming Ephapax-wasm CLI port needs but libgossamer didn't expose:

Export Capability Purpose
gossamer_shell_spawn(command, cap)opaque* Shell (kind=2) Background process spawn via /bin/sh -c (POSIX) or cmd /c (Windows).
gossamer_shell_kill(opaque*, cap)Result Shell (kind=2) SIGTERM / TerminateProcess, wait, free. Idempotent on null.
gossamer_fs_mkdir_p(path, cap)Result FileSystem (kind=0) Recursive mkdir; treats "already exists" as success.
gossamer_fs_copy_file(src, dst, cap)Result FileSystem (kind=0) Copy file, overwrite dst. Parent of dst must already exist.

Ephapax wrappers added to src/core/ShellExec.eph (spawn / spawnKill) and src/core/Filesystem.eph (mkdirP / copyFile) in matching legacy __ffi(...) style.

Why

Phase 14a.3 of porting the gossamer CLI to typed-wasm Ephapax. These are the gaps the CLI hits today:

  • cmdDev: needs background-spawn-then-kill for the user's frontend dev server. The current cli/src/main.zig uses Zig-native std.process.Child directly, which won't be reachable from wasm.
  • cmdBundle: needs recursive mkdir + file copy to assemble target/bundle/deb/usr/share/<id>/. The current code uses Zig-native std.fs.cwd().makePath / copyFile.

Once these exports exist, the wasm-host launcher (Phase 14a.5) only needs to dlopen libgossamer and forward the symbols — no Zig std reimplementation required on the wasm side.

Test plan

  • zig ast-check on shell.zig, filesystem.zig, main.zig — all clean.
  • Reviewer: CI's full GTK3/WebKitGTK build passes (local WSL env lacks the dev headers).
  • Reviewer: confirm capability taxonomy alignment — Shell (kind=2) for spawn/kill, FileSystem (kind=0) for mkdir_p/copy_file, matching Types.idr ResourceKind.

Notes

  • Synchronous gossamer_shell_execute (run-to-completion, capture stdout) is not added here. That's already declared in src/core/ShellExec.eph against a not-yet-implemented Zig symbol — a separate gap to close, not folded into this PR.
  • The legacy __ffi(...) syntax in the .eph wrappers matches the existing functions in those files. Rewriting src/core/*.eph to v2 grammar (extern blocks) is a separate workstream.

🤖 Generated with Claude Code

…ppers

Adds four capability-gated FFI exports the upcoming Ephapax-wasm CLI port
needs but libgossamer didn't expose:

  • gossamer_shell_spawn(command, cap_token) -> opaque*
      Spawns a process in the background via /bin/sh -c (POSIX) or cmd /c
      (Windows). Stdin/stdout/stderr inherit from the caller. Returns an
      opaque handle valid only for gossamer_shell_kill.
  • gossamer_shell_kill(opaque*, cap_token) -> Result
      Sends SIGTERM (or TerminateProcess on Windows), waits for exit,
      frees the wrapper. Idempotent on null.
  • gossamer_fs_mkdir_p(path, cap_token) -> Result
      Recursive mkdir; treats "already exists" as success.
  • gossamer_fs_copy_file(src, dst, cap_token) -> Result
      Copies a file, overwriting dst. Parent of dst must already exist.

All four go through the existing main.gossamer_cap_check /
gossamer_cap_resource_kind taxonomy: shell ops need Shell (kind=2), fs ops
need FileSystem (kind=0).

Shell.zig is a new file; filesystem.zig grows by two exports. The new
src/interface/ffi/src/shell.zig is wired into the comptime import block
in src/interface/ffi/src/main.zig so the exports actually land in
libgossamer's symbol table.

Ephapax wrappers added to src/core/ShellExec.eph (spawn / spawnKill) and
src/core/Filesystem.eph (mkdirP / copyFile) in the same legacy __ffi(...)
style as the existing functions in those files, so the surface is
consistent. (The v2-grammar rewrite of these modules is its own concern.)

Used by the gossamer CLI port:
  • cmdDev: shell.spawn replaces cli/src/main.zig's
    runShellCommandBackground for `beforeDevCommand`; spawnKill replaces
    the manual std.process.Child.kill in the defer block.
  • cmdBundle: fs.mkdirP creates target/bundle/deb/DEBIAN; fs.copyFile
    places gossamer.conf.json inside the package layout.

Verified:
  • zig ast-check on shell.zig, filesystem.zig, main.zig — all clean.
  • Full link to GTK3/WebKitGTK requires those system dev libs which
    aren't installed in this WSL env (pre-existing limitation); CI runs
    the full build.

Phase 14a.3 of the gossamer cli (cli/) port to typed-wasm Ephapax.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 31 issues detected

Severity Count
🔴 Critical 11
🟠 High 4
🟡 Medium 16

⚠️ Action Required: Critical security issues found!

View findings
[
  {
    "reason": "Issue in quality.yml",
    "type": "missing_workflow",
    "file": "quality.yml",
    "action": "create",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Issue in security-policy.yml",
    "type": "missing_workflow",
    "file": "security-policy.yml",
    "action": "create",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Action hyperpolymath/standards/.github/workflows/governance-reusable.yml@main needs attention",
    "type": "unpinned_action",
    "file": "governance.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Action actions/upload-artifact@v4 needs attention",
    "type": "unpinned_action",
    "file": "release.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Action actions/download-artifact@v4 needs attention",
    "type": "unpinned_action",
    "file": "release.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "believe_me undermines formal verification (1 occurrences, CWE-704)",
    "type": "believe_me",
    "file": "/home/runner/work/gossamer/gossamer/src/interface/abi/IPCDispatch.idr",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "critical"
  },
  {
    "reason": "believe_me undermines formal verification (1 occurrences, CWE-704)",
    "type": "believe_me",
    "file": "/home/runner/work/gossamer/gossamer/src/interface/abi/ResourceCleanup.idr",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "critical"
  },
  {
    "reason": "believe_me undermines formal verification (1 occurrences, CWE-704)",
    "type": "believe_me",
    "file": "/home/runner/work/gossamer/gossamer/src/interface/abi/GrooveTermination.idr",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "critical"
  },
  {
    "reason": "believe_me undermines formal verification (1 occurrences, CWE-704)",
    "type": "believe_me",
    "file": "/home/runner/work/gossamer/gossamer/src/interface/abi/HandleLinearity.idr",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "critical"
  },
  {
    "reason": "believe_me undermines formal verification (1 occurrences, CWE-704)",
    "type": "believe_me",
    "file": "/home/runner/work/gossamer/gossamer/src/interface/abi/WindowStateMachine.idr",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "critical"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

@hyperpolymath hyperpolymath merged commit 54058fd into main May 20, 2026
18 of 20 checks passed
hyperpolymath added a commit that referenced this pull request May 20, 2026
PRs #26 (shell + fs mkdir_p/copy_file) and #27 (conf JSON loader)
merged before their CHANGELOG entries landed. Backfills both under
[Unreleased] > Added in the same format as the existing Plugin-system
(Phase 6) entry: a top-level bolded title with phase + PR number,
followed by sub-bullets covering the FFI surface, capability gating,
Ephapax wrapper, and CLI-port consumers.

No code change.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

1 participant