feat(ts): add TypeScript source lift kit (self-hosted) + ts-language-signature#595
Conversation
…signature menagerie A self-hosted TypeScript source-language lift kit, mirroring PR #590 (the C# source lifter): a TypeScript program using the TypeScript compiler API that lifts TypeScript function definitions into ProvekIt function-contract mementos over a ts:-namespaced operation algebra, plus menagerie/ts-language-signature/ cataloging that algebra, plus a round-trip compiler. Built to the conventions #590's review rounds established: namespaced op CIDs, arity_shape on every op spec, a ts:source-unit lossless wrapper actually emitted, loud Refusals for unhandled syntax (no ts:unknown/skip catch-all), provably-unique fnName, effects on the canonical Effect wire shapes sorted by sort_key(), a lift(compile(lift(src))) round-trip test, deterministic JSON, version 0.1.0-draft. The existing ts kit surface manifest is untouched; the source lifter gets its own ts-source surface. vitest 6/6 + full suite 785 tests pass; tsc --noEmit pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
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 (80)
✨ 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.
Pull request overview
Adds a self-hosted TypeScript source lifter kit and a corresponding TypeScript language-signature menagerie entry, wiring the new authoring surface (typescript-source) into the CLI’s known surfaces and build/mint tooling.
Changes:
- Introduces
menagerie/typescript-language-signature/with sorts/ops/effects/equations specs and a mint script, plusmenagerie/manifest.yaml+Makefilewiring. - Adds a new TypeScript source lifter (
implementations/typescript/src/lift/typescript-source/) with NDJSON JSON-RPC (initialize/lift/compile/shutdown) and vitest coverage. - Registers the new
typescript-sourcesurface in the Rust CLI’sKNOWN_SURFACES.
Reviewed changes
Copilot reviewed 81 out of 81 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| Makefile | Adds a mint-typescript-language-signature convenience target and help text. |
| implementations/rust/provekit-cli/src/project_config.rs | Registers typescript-source in KNOWN_SURFACES and updates the anchor-entry test. |
| implementations/typescript/.provekit/lift/typescript-source/manifest.toml | New lift-kit manifest for the self-hosted TypeScript source lifter (RPC mode). |
| implementations/typescript/src/lift/typescript-source/bin.ts | New NDJSON JSON-RPC binary entrypoint exposing initialize/lift/compile/shutdown. |
| implementations/typescript/src/lift/typescript-source/index.test.ts | New vitest suite covering lifting, refusals, effect sorting, round-trip, and path traversal rejection. |
| implementations/typescript/src/lift/typescript-source/index.ts | New TypeScript compiler-API lifter + compiler/unwrapper for ts:-namespaced function-contract mementos and ts:source-unit wrapper. |
| menagerie/manifest.yaml | Adds a runnable destination entry for the TypeScript language signature mint script. |
| menagerie/typescript-language-signature/README.md | New README describing the TypeScript source language signature (draft). |
| menagerie/typescript-language-signature/mint.sh | New mint script mirroring other menagerie signature mint scripts. |
| menagerie/typescript-language-signature/specs/eff_io.spec.json | New effect operation spec for IO effects. |
| menagerie/typescript-language-signature/specs/eff_opaque_loop.spec.json | New effect operation spec for opaque loops keyed by CID. |
| menagerie/typescript-language-signature/specs/eff_panic.spec.json | New effect operation spec for panic/throw behavior. |
| menagerie/typescript-language-signature/specs/eff_read.spec.json | New effect operation spec for read effects. |
| menagerie/typescript-language-signature/specs/eff_unresolved_call.spec.json | New effect operation spec for unresolved calls. |
| menagerie/typescript-language-signature/specs/eff_write.spec.json | New effect operation spec for write effects. |
| menagerie/typescript-language-signature/specs/effsig_call.spec.json | New effect-signature catalog for call effects. |
| menagerie/typescript-language-signature/specs/effsig_io.spec.json | New effect-signature catalog for IO effects. |
| menagerie/typescript-language-signature/specs/effsig_loop.spec.json | New effect-signature catalog for loop effects. |
| menagerie/typescript-language-signature/specs/effsig_panic.spec.json | New effect-signature catalog for panic effects. |
| menagerie/typescript-language-signature/specs/effsig_read.spec.json | New effect-signature catalog for read effects. |
| menagerie/typescript-language-signature/specs/effsig_write.spec.json | New effect-signature catalog for write effects. |
| menagerie/typescript-language-signature/specs/eq_seq_assoc.spec.json | New equation spec for associativity of ts:seq. |
| menagerie/typescript-language-signature/specs/eq_seq_empty_left.spec.json | New equation spec for left-identity of empty ts:seq. |
| menagerie/typescript-language-signature/specs/eq_seq_empty_right.spec.json | New equation spec for right-identity of empty ts:seq. |
| menagerie/typescript-language-signature/specs/language_signature_typescript.spec.json | New TypeScript language-signature bundle spec referencing all sorts/ops/effects/equations and arity-shapes. |
| menagerie/typescript-language-signature/specs/op_add.spec.json | New operation spec for ts:add. |
| menagerie/typescript-language-signature/specs/op_and.spec.json | New operation spec for ts:and. |
| menagerie/typescript-language-signature/specs/op_args.spec.json | New operation spec for ts:args (variadic positional). |
| menagerie/typescript-language-signature/specs/op_assign.spec.json | New operation spec for ts:assign. |
| menagerie/typescript-language-signature/specs/op_bitand.spec.json | New operation spec for ts:bitand. |
| menagerie/typescript-language-signature/specs/op_bitnot.spec.json | New operation spec for ts:bitnot. |
| menagerie/typescript-language-signature/specs/op_bitor.spec.json | New operation spec for ts:bitor. |
| menagerie/typescript-language-signature/specs/op_bitxor.spec.json | New operation spec for ts:bitxor. |
| menagerie/typescript-language-signature/specs/op_break.spec.json | New operation spec for ts:break. |
| menagerie/typescript-language-signature/specs/op_call.spec.json | New operation spec for ts:call. |
| menagerie/typescript-language-signature/specs/op_continue.spec.json | New operation spec for ts:continue. |
| menagerie/typescript-language-signature/specs/op_decl.spec.json | New operation spec for ts:decl. |
| menagerie/typescript-language-signature/specs/op_div.spec.json | New operation spec for ts:div. |
| menagerie/typescript-language-signature/specs/op_eq.spec.json | New operation spec for ts:eq. |
| menagerie/typescript-language-signature/specs/op_for.spec.json | New operation spec for ts:for. |
| menagerie/typescript-language-signature/specs/op_ge.spec.json | New operation spec for ts:ge. |
| menagerie/typescript-language-signature/specs/op_gt.spec.json | New operation spec for ts:gt. |
| menagerie/typescript-language-signature/specs/op_if.spec.json | New operation spec for ts:if. |
| menagerie/typescript-language-signature/specs/op_index.spec.json | New operation spec for ts:index. |
| menagerie/typescript-language-signature/specs/op_ite.spec.json | New operation spec for ts:ite. |
| menagerie/typescript-language-signature/specs/op_le.spec.json | New operation spec for ts:le. |
| menagerie/typescript-language-signature/specs/op_lt.spec.json | New operation spec for ts:lt. |
| menagerie/typescript-language-signature/specs/op_member.spec.json | New operation spec for ts:member. |
| menagerie/typescript-language-signature/specs/op_mod.spec.json | New operation spec for ts:mod. |
| menagerie/typescript-language-signature/specs/op_mul.spec.json | New operation spec for ts:mul. |
| menagerie/typescript-language-signature/specs/op_ne.spec.json | New operation spec for ts:ne. |
| menagerie/typescript-language-signature/specs/op_neg.spec.json | New operation spec for ts:neg. |
| menagerie/typescript-language-signature/specs/op_new.spec.json | New operation spec for ts:new. |
| menagerie/typescript-language-signature/specs/op_not.spec.json | New operation spec for ts:not. |
| menagerie/typescript-language-signature/specs/op_nullish.spec.json | New operation spec for ts:nullish. |
| menagerie/typescript-language-signature/specs/op_or.spec.json | New operation spec for ts:or. |
| menagerie/typescript-language-signature/specs/op_pos.spec.json | New operation spec for ts:pos. |
| menagerie/typescript-language-signature/specs/op_postdec.spec.json | New operation spec for ts:postdec. |
| menagerie/typescript-language-signature/specs/op_postinc.spec.json | New operation spec for ts:postinc. |
| menagerie/typescript-language-signature/specs/op_predec.spec.json | New operation spec for ts:predec. |
| menagerie/typescript-language-signature/specs/op_preinc.spec.json | New operation spec for ts:preinc. |
| menagerie/typescript-language-signature/specs/op_return.spec.json | New operation spec for ts:return. |
| menagerie/typescript-language-signature/specs/op_seq.spec.json | New operation spec for ts:seq (variadic positional). |
| menagerie/typescript-language-signature/specs/op_shl.spec.json | New operation spec for ts:shl. |
| menagerie/typescript-language-signature/specs/op_shr.spec.json | New operation spec for ts:shr. |
| menagerie/typescript-language-signature/specs/op_source-unit.spec.json | New operation spec for ts:source-unit wrapper. |
| menagerie/typescript-language-signature/specs/op_sub.spec.json | New operation spec for ts:sub. |
| menagerie/typescript-language-signature/specs/op_throw.spec.json | New operation spec for ts:throw. |
| menagerie/typescript-language-signature/specs/op_typeof.spec.json | New operation spec for ts:typeof. |
| menagerie/typescript-language-signature/specs/op_ushr.spec.json | New operation spec for ts:ushr. |
| menagerie/typescript-language-signature/specs/op_while.spec.json | New operation spec for ts:while. |
| menagerie/typescript-language-signature/specs/sort_any.spec.json | New sort spec for ts:Any. |
| menagerie/typescript-language-signature/specs/sort_args.spec.json | New sort spec for ts:Args. |
| menagerie/typescript-language-signature/specs/sort_boolean.spec.json | New sort spec for ts:Boolean. |
| menagerie/typescript-language-signature/specs/sort_expr.spec.json | New sort spec for ts:Expr. |
| menagerie/typescript-language-signature/specs/sort_lvalue.spec.json | New sort spec for ts:LValue. |
| menagerie/typescript-language-signature/specs/sort_null.spec.json | New sort spec for ts:Null. |
| menagerie/typescript-language-signature/specs/sort_number.spec.json | New sort spec for ts:Number. |
| menagerie/typescript-language-signature/specs/sort_stmt.spec.json | New sort spec for ts:Stmt. |
| menagerie/typescript-language-signature/specs/sort_string.spec.json | New sort spec for ts:String. |
| menagerie/typescript-language-signature/specs/sort_unit.spec.json | New sort spec for ts:Unit. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| case "writes": return `1:writes:${effect.target}`; | ||
| case "io": return "2:io"; | ||
| case "panics": return "4:panics"; | ||
| case "unresolved_call": return `5:unresolved_call:${effect.name}`; |
| case "string": return primitiveSort("String"); | ||
| case "void": return primitiveSort("Unit"); | ||
| case "any": return primitiveSort("Any"); | ||
| case "unknown": return primitiveSort("Unknown"); |
| function emitStatementsFromTerm(term: IrTerm): ts.Statement[] { | ||
| if (isCtor(term, "ts:seq")) return termArgs(term).flatMap(emitStatementsFromTerm); | ||
| if (isCtor(term, "ts:return")) { | ||
| const args = termArgs(term); | ||
| return [ts.factory.createReturnStatement(args[0] ? expressionFromTerm(args[0]) : undefined)]; | ||
| } | ||
| if (isCtor(term, "ts:decl")) { | ||
| const args = termArgs(term); | ||
| const name = stringValue(args[0], "tmp"); | ||
| return [ts.factory.createVariableStatement(undefined, ts.factory.createVariableDeclarationList([ | ||
| ts.factory.createVariableDeclaration(sanitizeIdentifier(name), undefined, undefined, expressionFromTerm(args[1])), | ||
| ], ts.NodeFlags.Let))]; | ||
| } | ||
| if (isCtor(term, "ts:assign")) return [ts.factory.createExpressionStatement(expressionFromTerm(term))]; | ||
| if (isCtor(term, "ts:throw")) return [ts.factory.createThrowStatement(expressionFromTerm(termArgs(term)[0]))]; | ||
| if (isCtor(term, "ts:if")) { | ||
| const args = termArgs(term); | ||
| return [ts.factory.createIfStatement( | ||
| expressionFromTerm(args[0]), | ||
| ts.factory.createBlock(emitStatementsFromTerm(args[1] ?? seqTerm([])), true), | ||
| ts.factory.createBlock(emitStatementsFromTerm(args[2] ?? seqTerm([])), true), | ||
| )]; | ||
| } | ||
| if (isCtor(term, "ts:while")) { | ||
| const args = termArgs(term); | ||
| return [ts.factory.createWhileStatement( | ||
| expressionFromTerm(args[0]), | ||
| ts.factory.createBlock(emitStatementsFromTerm(args[1] ?? seqTerm([])), true), | ||
| )]; | ||
| } | ||
| return [ts.factory.createReturnStatement(expressionFromTerm(term))]; | ||
| } |
| @@ -0,0 +1,5 @@ | |||
| # TypeScript Source Language Signature | |||
|
|
|||
| Draft source-language operation algebra for the ProvekIt TypeScript source lifter. Operation CIDs are intentionally namespaced with `ts:` and describe TypeScript/JavaScript source AST constructs, not cross-language semantic equality. | |||
| - id: typescript-language-signature | ||
| path: typescript-language-signature | ||
| runnable: true | ||
| claim: TypeScript source AST operation algebra for ts:-namespaced function-contract mementos |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fff4c7b0ed
ℹ️ 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".
| locus: { file: fileContext.modulePath, line, col: 1 }, | ||
| autoMintedMementos: [], | ||
| }; | ||
| lifted.push({ contract, bodyTerm: postTerm }); |
There was a problem hiding this comment.
Store statement body in source-unit operational term
Use the full bodyTerm when populating lifted, not postTerm: for single-return functions this currently strips the ts:return wrapper and places an expression (for example ts:add) directly into ts:source-unit’s operational_term. That makes the generated source-unit term ill-typed against the Stmt sort and can break downstream validators/consumers that rely on statement-level operational projections.
Useful? React with 👍 / 👎.
| const loopTerm = ctor("ts:for", init, cond, update, emitStatement(stmt.statement, context)); | ||
| addEffect(context, { kind: "opaque_loop", loopCid: cidOfValue(loopTerm) }); |
There was a problem hiding this comment.
Add compile support for emitted for-loop terms
The lifter emits ts:for nodes, but the fallback compiler path does not handle ts:for in emitStatementsFromTerm/expressionFromTerm, so compileTypeScriptSourceIr throws cannot compile operation ts:for whenever callers compile IR that lacks a recoverable :<source-unit> wrapper (for example transformed/sliced IR documents). This creates a lift/compile mismatch for a syntax form the lifter itself produces.
Useful? React with 👍 / 👎.
| for (const stmt of statements) { | ||
| if (ts.isVariableStatement(stmt)) { | ||
| for (const decl of stmt.declarationList.declarations) { | ||
| if (ts.isIdentifier(decl.name)) vars.add(decl.name.text); |
There was a problem hiding this comment.
Namespace-qualify module variable effect targets
Module variables are collected by bare identifier only, including inside nested namespaces, so two namespace-scoped variables with the same name in one file collapse to the same effect cell (<modulePath>:<name>). In that case reads/writes from different state cells become indistinguishable, which corrupts emitted effect metadata and any analysis that depends on those targets.
Useful? React with 👍 / 👎.
Review: PR #595 —
|
| # | Item | Status |
|---|---|---|
| 1 | ts: prefix on every op; no ts:binop/ts:unknown catch-all |
✅ (test asserts no ts:skip/ts:unknown) |
| 2 | arity_shape on every op & sane (short-circuit, ite, seq, assign, branches) |
✅ |
| 3 | ts:source-unit(bytes, operational_term) op present & emitted with real bytes |
✅ |
| 4 | Refuse-not-fake: loud Refusal for unhandled SyntaxKind (arrows, async/await, generators, destructuring, spread, defaults, try/catch, switch, ?., template literals, as/satisfies, decorators, generics, JSX) |
✅ (verified live; switch/try-catch/JSX hit the default throw) |
| 5 | fnName = <module-path>:<qualified-name>; no collision |
✅ (syntactic path; overload sigs bodyless→refused) — TypeChecker-symbol not used (nit 4) |
| 6 | Effects on canonical wire shapes, sorted by sort_key(); no alloc/resolved-call |
✅ |
| 7 | Round-trip lift(compile(lift(src))) byte/CID-identity |
|
| 8 | Determinism (stable key order, no Map leak, no timestamps) | ✅ |
| 9 | CID-correctness: reuses the existing TS canonicalizer / BLAKE3 | ✅ |
| 10 | Wiring: typescript manifest not repointed; new typescript-source surface; KNOWN_SURFACES; no pin changes |
✅ |
| 11 | Existing TS kit still builds/tests (tsc --noEmit + 785 tests) |
✅ |
| 12 | RPC initialize/lift/compile/shutdown shapes match protocol |
✅ (compile is a non-standard extension also present in #590) |
Comparison to #590's bar
Meets or exceeds it. Same op-spec/effsig/sort/eq layout, same RPC surface (incl. the undocumented compile), same 0.1.0-draft + own-surface manifest pattern, same "don't repoint the kit surface" fix. Stricter in one respect: #590's C# lifter still ships a csharp:skip fallback op; #595 has none and the test actively forbids ts:skip/ts:unknown in lift output. Same draft-quality gaps as #590 (kit not minted/pinned). Net: ship it; file the follow-ups (round-trip test, manifest.yaml consistency, mint+pin).
— review by Claude (Opus 4.7, 1M ctx)
…stinct refusal reasons + drop spurious menagerie/manifest.yaml entry Review fixes for PR #595 (verdict was MERGE-WITH-NITS): (1) the lift(compile(lift(src))) test was tautological — compileTypeScriptSourceIr returns the stored <source-unit> bytes when one exists, so the ts.createPrinter AST-emit path was dead code under normal use; added compileTypeScriptSourceBodyIr so the test can compile a bare body term through the printer path, plus a canonical-byte/CID body-term round-trip test (kept the source-unit fast-path test too); (2) split the collapsed unsupported- function-shape refusal into a distinct reason per case (async / generator / decorator / generic / rest-param / default-param / destructured-param) so Refusal.reason is actionable; (3) removed the typescript-language-signature destination entry from menagerie/manifest.yaml (no *-language-signature catalog belongs in that list). NOTE: codex couldn't run tsc/vitest locally (sandbox blocked pnpm install — offline tarballs missing, online DNS ENOTFOUND); CI will verify. Co-Authored-By: Claude Opus 4.7 (1M context) <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>
…#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 TypeScript source-language lift kit +
menagerie/ts-language-signature/. Mirrors PR #590 (the C# source lifter).function-contractmementos overts:-namespaced opsts:source-unitlossless wrapper; round-tripcompile+ alift(compile(lift(src)))testarity_shapeon every op spec;Refusals (not fakes) for unhandled syntax; effects on the canonicalEffectwire shapes, sortedts-sourcelift surface (existingtskit surface manifest untouched — the lesson from feat(csharp): add C# language lifter with RPC protocol and menagerie signature #590);version 0.1.0-draft🤖 Generated with Claude Code