feat(zig): add Zig source lift kit (self-hosted) + zig-language-signature#596
Conversation
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (77)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ee631639c3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| try appendUniqueString(self.alloc, &self.known_functions, name); | ||
| try appendUniqueString(self.alloc, &self.known_functions, qualified); |
There was a problem hiding this comment.
Record namespace-only names for known functions
Calls to functions declared inside containers are misclassified as unresolved because exprName produces callees like Ns.func, but the known-function table only stores func and path.Ns.func. In a file with const Ns = struct { pub fn f() ... }, a call Ns.f() will incorrectly add an unresolved_call effect, which pollutes effect summaries and downstream memento requirements.
Useful? React with 👍 / 👎.
|
|
||
| fn emitString(self: *Lifter, node: Node.Index) !provekit.Term { | ||
| const raw = self.tree.getNodeSource(node); | ||
| if (raw.len >= 2 and raw[0] == '"' and raw[raw.len - 1] == '"') return provekit.Str(raw[1 .. raw.len - 1]); |
There was a problem hiding this comment.
Decode string literal escapes before building term constants
String literals are stored as raw token text without unescaping, so escape sequences like "\n" are represented as backslash+n instead of a newline character. This changes literal semantics in lifted IR and also breaks compile/lift round-tripping for escaped strings because recompilation escapes the backslashes again.
Useful? React with 👍 / 👎.
|
|
||
| fn zigTypeForSort(sort: provekit.Sort) []const u8 { | ||
| return switch (sort) { | ||
| .primitive => |name| if (std.mem.eql(u8, name, "Bool")) "bool" else if (std.mem.eql(u8, name, "Unit")) "void" else if (std.mem.eql(u8, name, "String")) "[]const u8" else "i32", |
There was a problem hiding this comment.
Map Ptr sort to a pointer type when recompiling contracts
Recompilation falls back to i32 for any primitive sort other than Bool/Unit/String, which includes Ptr produced by sortFromType for pointer parameters and returns. This makes generated Zig invalid or type-changed for pointer-using functions (e.g., emitted i32 with later .* dereference), so compile/lift round-trips fail on valid lifted inputs.
Useful? React with 👍 / 👎.
Review: PR #596 — Zig source lift kit (self-hosted)Verdict: MERGE-WITH-NITS — the kit is structurally sound, reuses the existing Zig canonicalizer/BLAKE3 (not a re-roll), refuses unhandled AST node tags loudly rather than faking ops, builds and tests clean; the nits are draft-grade gaps (string-escape fidelity, lift/compile surface asymmetry) that should be tracked before any non-draft promotion. The one thing to look at firstCID-correctness (item 9): confirmed good. Blocking findingsNone. Non-blocking findings (track before promoting past
|
| # | Item | Status | Note |
|---|---|---|---|
| 1 | zig: prefix on every op, no binop/unknown catch-all |
PASS | All 41 op_*.spec.json fn_names are zig:*; lifter's emitExpr else-branch is refuseFmt(... "unhandled Zig AST node tag"), not a synthesized op |
| 2 | arity_shape present & sane on every op |
PASS | binops named lhs/rhs; zig:seq/zig:unit/zig:unreachable positional; zig:assign named target/value; zig:and/zig:or mark rhs evaluation:"unevaluated"; mirrors the c11/csharp op-spec shape |
| 3 | zig:source-unit(bytes, operational_term) present AND emitted with real bytes |
PASS | op_source-unit.spec.json has the right shape; sourceUnitContract (lift.zig:611) emits zig:source-unit(Str(self.source), operational); verified via RPC the bytes are the verbatim source |
| 4 | Refuse-not-fake for unhandled AST tags (comptime/error-union/try/catch/errdefer/defer/suspend/resume/inline loops/switch/optional/@-builtins/anon structs/generics) |
PASS | All explicitly enumerated in emitStmt/emitExpr/sortFromType/emitFunction with structured Refusal{kind,function,line,reason}; AST-only, no Sema import; comptime params and anytype refused as unsupported-generic |
| 5 | fnName provably unique |
PASS (with caveat 5 above) | qualifiedName = path + namespace chain + name; no overloading in Zig; parse-error path returns empty declarations, no colliding fallback |
| 6 | Effects on canonical wire shapes, sorted by sort_key() |
PASS | Effect union = reads/writes/io/unsafe/panics/unresolved_call/opaque_loop with rank 0-6; Effect.lessThan does primary rank then secondary (std.mem.lessThan on target/name/cid); sorted via std.mem.sort before emission; no alloc, no resolved-call; opaque_loop.loopCid is blake3-512:...; unsafe is defined in the signature but not yet emitted by the lifter (acceptable for draft) |
| 7 | Round-trip lift(compile(lift(src))) byte/CID-identity, drives the real compiler |
PASS (narrow) | lift.zig:1107 checks canonicalTermBytes(bodyTerm()) equality through compileContract → real Ast.parse; compileContract renders actual Zig from the term (return (x + y);), no zig:source-unit byte-copy fast-path → the Go/Python/TS tautology nit does not apply. But the test covers only add; see non-blocking #2 |
| 8 | Determinism — stable key order, no HashMap iteration leak, no timestamps | PASS | ArrayList throughout; custom jsonStringify impls emit keys alphabetically; canonical bytes via provekit.jcsStringify; no AutoHashMap/StringHashMap; generate_assets.py re-run reproduces all 77 spec files byte-identically (git clean) |
| 9 | CID-correctness — reuses existing canonicalizer + BLAKE3 | PASS | See "the one thing to look at first" |
| 10 | Wiring — existing zig manifest not repointed; new zig-source surface manifest; version 0.1.0-draft; no .provekit/ci/accepted changes; no zig-language-signature in menagerie/manifest.yaml |
PASS | git diff shows existing implementations/zig/.provekit/lift/zig/manifest.toml untouched; new .provekit/lift/zig-source/manifest.toml with command = ["zig","build","run","--","--rpc"], working_dir = "provekit-lift-zig-source", version 0.1.0-draft; build.zig produces a provekit-lift-zig-source executable + a run step; zero ci//accepted//self-contract changes; grep language-signature menagerie/manifest.yaml → no match (clean); KNOWN_SURFACES in provekit-cli/src/project_config.rs gains "zig-source" next to clr-bytecode (same pattern as #590) |
| 11 | Existing Zig kit still builds | PASS | provekit-lift-zig zig build test and provekit-ir zig build test both green; Makefile's test-zig/build-zig extended (not replaced) to add provekit-lift-zig-source |
| 12 | --rpc initialize/lift/shutdown match the lift-plugin protocol |
PASS (with #4) | initialize returns name/version/protocol_version: "provekit-lift/1"/capabilities{authoring_surfaces,emits_signed_mementos,ir_version}; lift returns kind:"ir-document" + ir array; shutdown returns result:null; no compile RPC method (correct — the protocol has none; compileContract is internal-only for the round-trip test) |
Comparison to #590's bar
Meets it. Same shape as the CLR/csharp kits: separate module (correctly not folded into the annotation-adapter provekit-lift-zig), language-prefixed op algebra with a generated menagerie signature, refuse-don't-fake on anything outside the modeled subset, 0.1.0-draft version, reuses the kit's own canonicalizer. The string-escape gap (#1) is the one item I'd want closed before this surface graduates from draft; #590's reviewers would have weighted the canonicalizer-reuse question highest, and that one is clean.
— review by Claude (Opus 4.7, 1M ctx), worktree build/test on zig 0.16.0
There was a problem hiding this comment.
Pull request overview
Adds a new self-hosted Zig source lift kit (zig-source) plus a draft Zig language-signature menagerie entry, aligning with the repo’s lift-plugin protocol approach (JSON-RPC over stdio) and the existing “language signature” catalog structure.
Changes:
- Introduces
implementations/zig/provekit-lift-zig-source(RPC entrypoint + AST lifter + unit tests) and registers it as a project-local lift surface (zig-source). - Adds
menagerie/zig-language-signature/with generated sort/op/equation/effect-signature specs and a generator script. - Extends
make test-zig/build-zigand CLI known surfaces to includezig-source.
Reviewed changes
Copilot reviewed 77 out of 77 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| Makefile | Adds menagerie generation target and builds/tests the new Zig source lifter as part of Zig CI targets. |
| implementations/rust/provekit-cli/src/project_config.rs | Registers zig-source as a known authoring surface in the CLI. |
| implementations/zig/.provekit/lift/zig-source/manifest.toml | Adds project-local lift-plugin manifest for the new zig-source surface. |
| implementations/zig/provekit-lift-zig-source/build.zig.zon | Declares the new Zig package metadata for provekit-lift-zig-source. |
| implementations/zig/provekit-lift-zig-source/build.zig | Zig build wiring for the lifter module, executable, and unit tests. |
| implementations/zig/provekit-lift-zig-source/src/main.zig | JSON-RPC (lift-plugin protocol) stdin/stdout loop and request handling for initialize/lift/shutdown. |
| implementations/zig/provekit-lift-zig-source/src/lift.zig | Core Zig AST lifter emitting function-contract mementos + effects + compile/roundtrip helpers + tests. |
| menagerie/zig-language-signature/README.md | Documents the draft Zig source algebra and effect vocabulary. |
| menagerie/zig-language-signature/generate_assets.py | Script that generates the Zig language-signature spec JSON assets. |
| menagerie/zig-language-signature/specs/language_signature_zig.spec.json | Top-level Zig language signature catalog referencing sorts/ops/equations/effect signatures. |
| menagerie/zig-language-signature/specs/sort_bool.spec.json | Zig signature sort spec. |
| menagerie/zig-language-signature/specs/sort_bottom.spec.json | Zig signature sort spec. |
| menagerie/zig-language-signature/specs/sort_expr.spec.json | Zig signature sort spec. |
| menagerie/zig-language-signature/specs/sort_fieldname.spec.json | Zig signature sort spec. |
| menagerie/zig-language-signature/specs/sort_int.spec.json | Zig signature sort spec. |
| menagerie/zig-language-signature/specs/sort_listofexpr.spec.json | Zig signature sort spec. |
| menagerie/zig-language-signature/specs/sort_lvalue.spec.json | Zig signature sort spec. |
| menagerie/zig-language-signature/specs/sort_ptr.spec.json | Zig signature sort spec. |
| menagerie/zig-language-signature/specs/sort_reason.spec.json | Zig signature sort spec. |
| menagerie/zig-language-signature/specs/sort_stmt.spec.json | Zig signature sort spec. |
| menagerie/zig-language-signature/specs/sort_string.spec.json | Zig signature sort spec. |
| menagerie/zig-language-signature/specs/sort_unit.spec.json | Zig signature sort spec. |
| menagerie/zig-language-signature/specs/op_add.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_addr.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_and.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_assign.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_bitand.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_bitnot.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_bitor.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_bitxor.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_break.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_call.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_cast.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_continue.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_decl.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_deref.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_div.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_eq.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_field.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_for.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_ge.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_gt.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_if.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_index.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_le.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_lt.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_mod.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_mul.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_ne.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_neg.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_not.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_or.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_panic.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_return.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_seq.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_shl.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_shr.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_skip.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_source-unit.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_sub.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_unit.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_unreachable.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/op_while.spec.json | Zig signature operation spec. |
| menagerie/zig-language-signature/specs/eq_and_false.spec.json | Zig signature equation spec. |
| menagerie/zig-language-signature/specs/eq_and_true.spec.json | Zig signature equation spec. |
| menagerie/zig-language-signature/specs/eq_or_false.spec.json | Zig signature equation spec. |
| menagerie/zig-language-signature/specs/eq_or_true.spec.json | Zig signature equation spec. |
| menagerie/zig-language-signature/specs/eq_seq_assoc.spec.json | Zig signature equation spec. |
| menagerie/zig-language-signature/specs/eq_seq_skip_left.spec.json | Zig signature equation spec. |
| menagerie/zig-language-signature/specs/eq_seq_skip_right.spec.json | Zig signature equation spec. |
| menagerie/zig-language-signature/specs/effsig_io.spec.json | Zig effect-signature spec (currently shaped inconsistently with repo minting expectations). |
| menagerie/zig-language-signature/specs/effsig_opaque_loop.spec.json | Zig effect-signature spec (currently shaped inconsistently with repo minting expectations). |
| menagerie/zig-language-signature/specs/effsig_panic.spec.json | Zig effect-signature spec (currently shaped inconsistently with repo minting expectations). |
| menagerie/zig-language-signature/specs/effsig_read.spec.json | Zig effect-signature spec (currently shaped inconsistently with repo minting expectations). |
| menagerie/zig-language-signature/specs/effsig_unresolved_call.spec.json | Zig effect-signature spec (currently shaped inconsistently with repo minting expectations). |
| menagerie/zig-language-signature/specs/effsig_unsafe.spec.json | Zig effect-signature spec (currently shaped inconsistently with repo minting expectations). |
| menagerie/zig-language-signature/specs/effsig_write.spec.json | Zig effect-signature spec (currently shaped inconsistently with repo minting expectations). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "kind": "effect-signature", | ||
| "version": "0.1.0-draft", | ||
| "fn_name": "zig:effect:IO", | ||
| "formals": [], | ||
| "return_sort": { | ||
| "kind": "ctor", | ||
| "name": "Unit", | ||
| "args": [] | ||
| }, | ||
| "pre": { | ||
| "kind": "atomic", | ||
| "name": "true", | ||
| "args": [] | ||
| }, | ||
| "post": { | ||
| "kind": "effect-signature-description", | ||
| "name": "IO" | ||
| }, | ||
| "effects": { | ||
| "effects": [] | ||
| }, |
| "kind": "effect-signature", | ||
| "version": "0.1.0-draft", | ||
| "fn_name": "zig:effect:MemRead", | ||
| "formals": [], | ||
| "return_sort": { | ||
| "kind": "ctor", | ||
| "name": "Unit", | ||
| "args": [] | ||
| }, | ||
| "pre": { | ||
| "kind": "atomic", | ||
| "name": "true", | ||
| "args": [] | ||
| }, | ||
| "post": { | ||
| "kind": "effect-signature-description", | ||
| "name": "MemRead" | ||
| }, | ||
| "effects": { | ||
| "effects": [] | ||
| }, |
| "kind": "effect-signature", | ||
| "version": "0.1.0-draft", | ||
| "fn_name": "zig:effect:MemWrite", | ||
| "formals": [], | ||
| "return_sort": { | ||
| "kind": "ctor", | ||
| "name": "Unit", | ||
| "args": [] | ||
| }, | ||
| "pre": { | ||
| "kind": "atomic", | ||
| "name": "true", | ||
| "args": [] | ||
| }, | ||
| "post": { | ||
| "kind": "effect-signature-description", | ||
| "name": "MemWrite" | ||
| }, | ||
| "effects": { | ||
| "effects": [] | ||
| }, |
| "kind": "effect-signature", | ||
| "version": "0.1.0-draft", | ||
| "fn_name": "zig:effect:Panic", | ||
| "formals": [], | ||
| "return_sort": { | ||
| "kind": "ctor", | ||
| "name": "Unit", | ||
| "args": [] | ||
| }, | ||
| "pre": { | ||
| "kind": "atomic", | ||
| "name": "true", | ||
| "args": [] | ||
| }, | ||
| "post": { | ||
| "kind": "effect-signature-description", | ||
| "name": "Panic" | ||
| }, | ||
| "effects": { | ||
| "effects": [] | ||
| }, |
| "kind": "effect-signature", | ||
| "version": "0.1.0-draft", | ||
| "fn_name": "zig:effect:UnresolvedCall", | ||
| "formals": [], | ||
| "return_sort": { | ||
| "kind": "ctor", | ||
| "name": "Unit", | ||
| "args": [] | ||
| }, | ||
| "pre": { | ||
| "kind": "atomic", | ||
| "name": "true", | ||
| "args": [] | ||
| }, | ||
| "post": { | ||
| "kind": "effect-signature-description", | ||
| "name": "UnresolvedCall" | ||
| }, | ||
| "effects": { | ||
| "effects": [] | ||
| }, |
| "kind": "effect-signature", | ||
| "version": "0.1.0-draft", | ||
| "fn_name": "zig:effect:Unsafe", | ||
| "formals": [], | ||
| "return_sort": { | ||
| "kind": "ctor", | ||
| "name": "Unit", | ||
| "args": [] | ||
| }, | ||
| "pre": { | ||
| "kind": "atomic", | ||
| "name": "true", | ||
| "args": [] | ||
| }, | ||
| "post": { | ||
| "kind": "effect-signature-description", | ||
| "name": "Unsafe" | ||
| }, | ||
| "effects": { | ||
| "effects": [] | ||
| }, |
| "kind": "effect-signature", | ||
| "version": "0.1.0-draft", | ||
| "fn_name": "zig:effect:OpaqueLoop", | ||
| "formals": [], | ||
| "return_sort": { | ||
| "kind": "ctor", | ||
| "name": "Unit", | ||
| "args": [] | ||
| }, | ||
| "pre": { | ||
| "kind": "atomic", | ||
| "name": "true", | ||
| "args": [] | ||
| }, | ||
| "post": { | ||
| "kind": "effect-signature-description", | ||
| "name": "OpaqueLoop" | ||
| }, | ||
| "effects": { | ||
| "effects": [] | ||
| }, |
| for key, name in { | ||
| "read": "MemRead", "write": "MemWrite", "io": "IO", "unsafe": "Unsafe", "panic": "Panic", "unresolved_call": "UnresolvedCall", "opaque_loop": "OpaqueLoop", | ||
| }.items(): | ||
| write(SPECS / f"effsig_{key}.spec.json", { | ||
| "kind": "effect-signature", | ||
| "version": VERSION, | ||
| "fn_name": f"zig:effect:{name}", | ||
| "formals": [], | ||
| "return_sort": sort("Unit"), | ||
| "pre": true_formula(), | ||
| "post": {"kind": "effect-signature-description", "name": name}, | ||
| "effects": {"effects": []}, | ||
| "locus": LOCUS, | ||
| }) |
| } | ||
| if (std.mem.eql(u8, op, "zig:unreachable")) return out.appendSlice(alloc, "unreachable"); | ||
| if (std.mem.eql(u8, op, "zig:unit")) return out.appendSlice(alloc, "{}"); | ||
| try out.appendSlice(alloc, "unreachable"); |
| "effect_signatures": [ | ||
| "effsig_io.spec.json", | ||
| "effsig_opaque_loop.spec.json", | ||
| "effsig_panic.spec.json", | ||
| "effsig_read.spec.json", | ||
| "effsig_unresolved_call.spec.json", | ||
| "effsig_unsafe.spec.json", | ||
| "effsig_write.spec.json" | ||
| ], |
…ue in the IR-to-Zig compiler Review nit-fixes for PR #596 (verdict was MERGE-WITH-NITS): (1) emitString refused to decode escape sequences — a Zig "oops\n" lifted to a Str term with a literal backslash-n, so the canonical term (and its CID) misrepresented the runtime value; now any string literal containing \ is refused with Refusal{kind:'unsupported-string-escape'} rather than lifted wrong (the Supra-omnia-rectum-aligned choice); (2) compileContract (the IR-to-Zig path) didn't handle zig:for / zig:break / zig:continue (they fell to a literal "unreachable"), so loop-bearing functions wouldn't round-trip and the single zig:add round-trip test camouflaged it; now those ops emit the corresponding Zig syntax and a loop-body canonical-byte round-trip test (via provekit-ir's jcsStringify/jcsHash) exercises it. make test-zig passes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ture menagerie A self-hosted Zig source-language lift kit, mirroring PR #590 (the C# source lifter): a Zig program using std.zig.Ast that lifts Zig function definitions into ProvekIt function-contract mementos over a zig:-namespaced operation algebra, plus menagerie/zig-language-signature/, plus a round-trip compiler. Built to the conventions #590's review rounds established: namespaced op CIDs, arity_shape on every op spec, a zig:source-unit lossless wrapper actually emitted, loud Refusals for unhandled syntax (comptime / error unions / try-catch / defer / async / inline-for / switch / @-builtins are refused; no zig:unknown/skip catch-all), provably-unique qualified fnName, effects on the canonical Effect wire shapes sorted by sort_key(), BLAKE3/JCS loop CIDs, a lift(compile(lift(src))) round-trip test, version 0.1.0-draft. The existing zig kit surface manifest (provekit-lift-zig) is untouched; the source lifter gets its own zig-source surface. make test-zig + zig build test pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ue in the IR-to-Zig compiler Review nit-fixes for PR #596 (verdict was MERGE-WITH-NITS): (1) emitString refused to decode escape sequences — a Zig "oops\n" lifted to a Str term with a literal backslash-n, so the canonical term (and its CID) misrepresented the runtime value; now any string literal containing \ is refused with Refusal{kind:'unsupported-string-escape'} rather than lifted wrong (the Supra-omnia-rectum-aligned choice); (2) compileContract (the IR-to-Zig path) didn't handle zig:for / zig:break / zig:continue (they fell to a literal "unreachable"), so loop-bearing functions wouldn't round-trip and the single zig:add round-trip test camouflaged it; now those ops emit the corresponding Zig syntax and a loop-body canonical-byte round-trip test (via provekit-ir's jcsStringify/jcsHash) exercises it. make test-zig passes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
88cc382 to
ac38549
Compare
…#596/#598/#599/#600 Per-kit changes: - rust/provekit-cli: extend KNOWN_SURFACES anchor test to assert ruby-source, csharp-source, swift-source, zig-source are all registered (were in the array, not in the test) - Makefile: wire test-ruby and test-php into test-all so the new lift kits run under ci (boy-scout -- flagged in #598 review) - typescript-language-signature/mint.sh: replace find with explicit enumeration to match c11/rust pattern and remove portability footgun (PR #595 nit #3) - ruby/ruby_source.rb: add instance_variable_get, instance_variable_set, const_get, const_set to METAPROGRAMMING_CALLS (PR #598 nit #4) - php/PhpSourceCompiler.php: simplify isUnit() to remove precedence-reliant double-condition (PR #600 nit #2) Already swept on origin/main (codex/lift-kit-nits-cleanup, empty cherry-picks confirmed): - effect sort-key alignment: 5:unresolved_call -> 5:unresolved: (ruby + swift) - csharp-source backfill in KNOWN_SURFACES - swift: emit Refusal for unparseable function signatures + ThrowStmt API fix Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rm bytes match source semantics (#639) The lifter was refusing all string literals containing escape sequences (\n, \t, \\, \", \xNN, \u{NNNN}) with `unsupported-string-escape`. This meant any Zig source with escape sequences could not be lifted at all, and no CID could be produced. The stopgap refusal was a placeholder from PR #596. Fix: - `.string_literal`: use `std.zig.string_literal.parseAlloc` (Zig stdlib) to decode all escape sequences per spec. Returns decoded bytes to IR; the CID now hashes the runtime value, not the source text. - `.multiline_string_literal`: walk the `multiline_string_literal_line` tokens, strip the `\\` two-byte prefix from each, join with `\n`. Multiline strings have no escape sequences per Zig spec; they are raw byte content. - `appendEscapedString` (pretty-printer path): extended to handle `\r`, `\t`, and a `\xNN` fallback for all other non-printable bytes so that `lift(compile(lift(src)))` round-trips correctly for all decoded string content. CID drift: 0 committed fixtures moved. No existing zig-language- signature or cross-language-port fixture exercised string literals with escapes (they were being refused, so none could have been committed). The regression tests are the new pins. Boy-scout: char_literal is already refused (unchanged). Numeric literals with underscores work correctly via std.fmt.parseInt base-0. No unrelated changes in this PR. New regression tests (7 added, 1 updated): - decodes \\n escape in string literal to newline byte in IR term - decodes \\t and \\r escape sequences in string literals - decodes \\x hex escape to raw byte - decodes \\u{NNNN} unicode escape to UTF-8 bytes - decodes \\\\ escaped backslash to single backslash byte - lifts multiline string literal as raw decoded bytes - round trip string literal with escape sequences preserves decoded bytes Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…#596/#598/#599/#600 Per-kit changes: - rust/provekit-cli: extend KNOWN_SURFACES anchor test to assert ruby-source, csharp-source, swift-source, zig-source are all registered (were in the array, not in the test) - Makefile: wire test-ruby and test-php into test-all so the new lift kits run under ci (boy-scout -- flagged in #598 review) - typescript-language-signature/mint.sh: replace find with explicit enumeration to match c11/rust pattern and remove portability footgun (PR #595 nit #3) - ruby/ruby_source.rb: add instance_variable_get, instance_variable_set, const_get, const_set to METAPROGRAMMING_CALLS (PR #598 nit #4) - php/PhpSourceCompiler.php: simplify isUnit() to remove precedence-reliant double-condition (PR #600 nit #2) Already swept on origin/main (codex/lift-kit-nits-cleanup, empty cherry-picks confirmed): - effect sort-key alignment: 5:unresolved_call -> 5:unresolved: (ruby + swift) - csharp-source backfill in KNOWN_SURFACES - swift: emit Refusal for unparseable function signatures + ThrowStmt API fix Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…599/#600 (#632) * chore(lift-kits): sweep accumulated MERGE-WITH-NITS nits from PRs #595/#596/#598/#599/#600 Per-kit changes: - rust/provekit-cli: extend KNOWN_SURFACES anchor test to assert ruby-source, csharp-source, swift-source, zig-source are all registered (were in the array, not in the test) - Makefile: wire test-ruby and test-php into test-all so the new lift kits run under ci (boy-scout -- flagged in #598 review) - typescript-language-signature/mint.sh: replace find with explicit enumeration to match c11/rust pattern and remove portability footgun (PR #595 nit #3) - ruby/ruby_source.rb: add instance_variable_get, instance_variable_set, const_get, const_set to METAPROGRAMMING_CALLS (PR #598 nit #4) - php/PhpSourceCompiler.php: simplify isUnit() to remove precedence-reliant double-condition (PR #600 nit #2) Already swept on origin/main (codex/lift-kit-nits-cleanup, empty cherry-picks confirmed): - effect sort-key alignment: 5:unresolved_call -> 5:unresolved: (ruby + swift) - csharp-source backfill in KNOWN_SURFACES - swift: emit Refusal for unparseable function signatures + ThrowStmt API fix Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(ruby-language-signature): regen op_source-unit.spec.json with notes field The generator `generate_assets.py` was updated to emit a `notes` field on the `source-unit` op spec but the committed file was never regenerated. CI gate at Makefile:606 (`generate_assets.py --check`) caught the staleness. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * ci: add composer to conformance job apt block (fixes test-php exit 127) test-php runs `composer install && composer test`; the conformance job installed php-cli but never composer, so the command was not found. Adds the `composer` Ubuntu apt package to the shared system-deps step so make test-all (and make ci) can reach it. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Self-hosted Zig source-language lift kit +
menagerie/zig-language-signature/. Mirrors PR #590 (the C# source lifter).std.zig.Ast→function-contractmementos overzig:-namespaced opszig:source-unitlossless wrapper; round-tripcompile+ alift(compile(lift(src)))testarity_shapeon every op spec;Refusals (not fakes) for comptime/error-unions/try-catch/defer/async/inline-for/switch/@-builtins; effects on the canonicalEffectwire shapes, sorted; BLAKE3/JCS loop CIDszig-sourcelift surface (existingzigkit surface manifestprovekit-lift-ziguntouched — the lesson from feat(csharp): add C# language lifter with RPC protocol and menagerie signature #590);version 0.1.0-draftmake test-zig+zig build testpass🤖 Generated with Claude Code