feat(stdlib/json): v0.3 — RSR rewire to hpm-json-rsr Zig FFI#421
Merged
Conversation
Adds the long-deferred `parse: String -> Option<HpmJsonValue>` bridge to stdlib/json.affine, completing echidna#63's deferred boundary without hand-rolling a parser. The implementation routes through the `hyperpolymath/hpm-json-rsr` Zig FFI exports — 11 in total, declared verbatim as `pub extern fn hpm_json_*`. The new `to_json` walker materialises non-object subtrees (leaves + arrays) into the existing `Json` sum; objects descend lazily via `hpm_json_object_get` (the Zig FFI does not yet export key enumeration, deferred). Deno-ESM lowering (`lib/codegen_deno.ml`) maps each `hpm_json_*` to `__as_hpmJson*` JS shims, with handles as the underlying JS value from `JSON.parse` (free is a no-op; GC reclaims). Native targets will link against the hpm-json-rsr cdylib using the same extern surface. Smoke-verified end-to-end on Deno: object descent (installation.id => 12345), array materialisation (JArray), and malformed-JSON => None all pass. Estate-vocabulary note: "Zig FFI" not "C-ABI" — the wire-level C calling convention is an implementation detail of Zig's `export fn`, not something AffineScript consumers need to think about. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
🔍 Hypatia Security ScanFindings: 81 issues detected
View findings[
{
"reason": "Action actions/checkout@v6 needs attention",
"type": "unpinned_action",
"file": "publish-jsr.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Action denoland/setup-deno@v2 needs attention",
"type": "unpinned_action",
"file": "publish-jsr.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in affine-vscode-publish.yml",
"type": "unknown",
"file": "affine-vscode-publish.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in casket-pages.yml",
"type": "unknown",
"file": "casket-pages.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in casket-pages.yml",
"type": "unknown",
"file": "casket-pages.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in ci.yml",
"type": "unknown",
"file": "ci.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in ci.yml",
"type": "unknown",
"file": "ci.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in ci.yml",
"type": "unknown",
"file": "ci.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in ci.yml",
"type": "unknown",
"file": "ci.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in ci.yml",
"type": "unknown",
"file": "ci.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
hyperpolymath
added a commit
that referenced
this pull request
May 28, 2026
hyperpolymath
added a commit
that referenced
this pull request
May 28, 2026
This reverts commit e3a4724.
🔍 Hypatia Security ScanFindings: 81 issues detected
View findings[
{
"reason": "Action actions/checkout@v6 needs attention",
"type": "unpinned_action",
"file": "publish-jsr.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Action denoland/setup-deno@v2 needs attention",
"type": "unpinned_action",
"file": "publish-jsr.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in affine-vscode-publish.yml",
"type": "unknown",
"file": "affine-vscode-publish.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in casket-pages.yml",
"type": "unknown",
"file": "casket-pages.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in casket-pages.yml",
"type": "unknown",
"file": "casket-pages.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in ci.yml",
"type": "unknown",
"file": "ci.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in ci.yml",
"type": "unknown",
"file": "ci.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in ci.yml",
"type": "unknown",
"file": "ci.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in ci.yml",
"type": "unknown",
"file": "ci.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in ci.yml",
"type": "unknown",
"file": "ci.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Completes the long-deferred
parse: String -> Option<HpmJsonValue>bridge instdlib/json.affineby routing through thehyperpolymath/hpm-json-rsrZig FFI (11 exports) instead of hand-rolling a parser. Closes the echidna#63 "parse bridge" gap and unblocks the OikosBot AffineScript port's webhook payload extraction (oikos#41 +bot-integration-affine/).What lands
stdlib/json.affinev0.3 — opaquepub extern type HpmJsonValue+ 11hpm_json_*externs mirroring the Zig exports verbatim, plus:pub fn parse(src: String) -> Option<HpmJsonValue>(handle-returning; caller owns + must free)pub fn to_json(val: HpmJsonValue) -> Option<Json>(tree-walk; materialises leaves + arrays; objects descend lazily viahpm_json_object_get)lib/codegen_deno.ml— Deno-ESM lowering: 11 entries indeno_builtinsmappinghpm_json_*→__as_hpmJson*JS shims (handle == JS value;JSON.parsepowershpm_json_parse;hpm_json_freeis a no-op since GC reclaims).Object-key enumeration gap
The Zig FFI does not (yet) export an
hpm_json_object_keysfunction, soto_jsoncannot materialise objects into a fullJObject(...)sum. This is honest: object payloads (e.g. GitHub webhooks) descend lazily by known key viahpm_json_object_get+ leaf-extract — exactly how the OikosBot port needs to use it. A follow-up PR tohpm-json-rsrwill addhpm_json_object_keysto close the round-trip.Verification
affinescript check stdlib/json.affine— type checksdune build— cleandune runtest— same 2 pre-existing failures asmain, no regressions{"installation":{"id":12345}}→12345), array materialisation ([1,2,3]→JArray), malformed JSON →NoneVocabulary
"Zig FFI" not "C-ABI" — the wire-level C calling convention is an implementation detail of Zig's
export fn. Estate convention is Zig=FFIs / Idris2=ABIs.Test plan
affinescript check stdlib/json.affine)🤖 Generated with Claude Code