Skip to content

feat(ffi,core): conf — real JSON loader for gossamer.conf.json#27

Merged
hyperpolymath merged 2 commits into
mainfrom
feat/cli-ffi-conf-load
May 20, 2026
Merged

feat(ffi,core): conf — real JSON loader for gossamer.conf.json#27
hyperpolymath merged 2 commits into
mainfrom
feat/cli-ffi-conf-load

Conversation

@hyperpolymath
Copy link
Copy Markdown
Owner

Summary

Replaces the hand-rolled string-scan config parser in cli/src/main.zig with a proper std.json-backed loader exposed through libgossamer.

Export Capability Notes
gossamer_conf_load(path, cap)opaque* FileSystem (kind=0) Parse JSON file (256 KB cap, matches existing CLI).
gossamer_conf_get_string(c*, path)*char|null Null-terminated dupe owned by the Conf.
gossamer_conf_get_int(c*, path, default)i64 Accepts integer and (truncated) float.
gossamer_conf_get_bool(c*, path, default)i32 0/1.
gossamer_conf_has(c*, path)i32 0/1.
gossamer_conf_free(c*)void Frees tree + all dupes; safe on null.

Dotted paths so callers target nested keys explicitly:

"productName"             top-level string
"build.devUrl"            nested string
"app.windows.0.width"     nested int inside an array element

Adds src/core/Conf.eph wrapper in matching legacy __ffi(...) style.

Why

The previous string-scan parser just found the first occurrence of "<key>": regardless of nesting — fragile when a key name (e.g. title) appears at multiple depths. Real parsing fixes that, and gives the upcoming Ephapax-wasm CLI a config-reading FFI it can call without re-implementing JSON inside the wasm guest.

This is Phase 14a.4 of porting the gossamer CLI to typed-wasm Ephapax. With 14a.1 (#86 on ephapax), 14a.2 (#24), 14a.3 (#26), and this PR, the only outstanding prep is 14a.5 (the wasm-host launcher) before the actual port (#15).

Memory model

Strings returned by get_string are null-terminated dupes owned by the Conf handle (tracked in string_dupes: ArrayListUnmanaged([:0]u8)). They're freed together by gossamer_conf_free so the C caller never has to free them individually. Documented in the Conf.eph wrapper too.

Test plan

  • zig ast-check on conf.zig + main.zig — clean.
  • zig test -lc conf.zig shows the only failures come from sibling files needing gtk/gtk.h headers; conf.zig itself has no glib/GTK dependency.
  • Reviewer: CI's full build passes with system deps.
  • Reviewer: spot-check a dotted-path lookup against a real gossamer.conf.json (e.g. build.devUrl, app.windows.0.width).

🤖 Generated with Claude Code

Replaces the hand-rolled string-scan parser in cli/src/main.zig
(parseConfig + extractStringField/IntField/BoolField) with a proper
std.json-backed loader exposed through libgossamer.

Surface (all capability-gated on FileSystem, kind=0):

  • gossamer_conf_load(path, cap_token)            -> opaque*  | null
  • gossamer_conf_get_string(conf*, dotted_path)   -> *char    | null
  • gossamer_conf_get_int(conf*, path, default)    -> i64
  • gossamer_conf_get_bool(conf*, path, default)   -> i32  (0/1)
  • gossamer_conf_has(conf*, path)                 -> i32  (0/1)
  • gossamer_conf_free(conf*)                      -> void

Dotted-path lookups so callers target nested keys explicitly:
  "productName"             top-level string
  "build.devUrl"            nested string
  "app.windows.0.width"     nested int inside an array element

The old scanner just found the first occurrence of `"<key>":` regardless
of nesting — fragile when a key (e.g. "title") appears at multiple
depths. Real parsing fixes that, and the Ephapax-wasm CLI port now has a
config-reading FFI it can call without a JSON parser inside the guest.

Memory model: strings returned by get_string are null-terminated dupes
owned by the Conf handle (tracked in `string_dupes`). They're freed
together by gossamer_conf_free so the C caller never has to free them
individually.

Adds src/core/Conf.eph wrapper in the same legacy __ffi(...) style as
sibling modules (ShellExec / Filesystem). The v2-grammar extern-block
rewrite of src/core/*.eph is its own concern.

Verified:
  • zig ast-check on conf.zig + main.zig — clean.
  • Full type-check via `zig test -lc conf.zig` fails only because
    transitively-imported siblings (dialog.zig, tray.zig, webview_gtk.zig)
    need gtk/gtk.h which isn't installed in this WSL env. conf.zig itself
    has no glib/GTK dependency. CI runs the full build with deps.

Phase 14a.4 of the gossamer cli (cli/) port to typed-wasm Ephapax. With
this PR plus 14a.1-3, the only outstanding prep is 14a.5 (the wasm-host
launcher) before #15 (the port itself).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@@ -0,0 +1,218 @@
// Gossamer — Conf FFI Implementation
@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 enabled auto-merge (squash) May 20, 2026 08:25
@hyperpolymath hyperpolymath disabled auto-merge May 20, 2026 08:25
@hyperpolymath hyperpolymath merged commit 8cfb7b6 into main May 20, 2026
14 of 15 checks passed
@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 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>
@hyperpolymath hyperpolymath deleted the feat/cli-ffi-conf-load branch May 20, 2026 13:08
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