Skip to content

feat(ts): add TypeScript source lift kit (self-hosted) + ts-language-signature#595

Merged
TSavo merged 2 commits into
mainfrom
codex/typescript-source-lift-kit
May 11, 2026
Merged

feat(ts): add TypeScript source lift kit (self-hosted) + ts-language-signature#595
TSavo merged 2 commits into
mainfrom
codex/typescript-source-lift-kit

Conversation

@TSavo
Copy link
Copy Markdown
Owner

@TSavo TSavo commented May 11, 2026

Self-hosted TypeScript source-language lift kit + menagerie/ts-language-signature/. Mirrors PR #590 (the C# source lifter).

  • TypeScript lifter via the TypeScript compiler API → function-contract mementos over ts:-namespaced ops
  • per-file ts:source-unit lossless wrapper; round-trip compile + a lift(compile(lift(src))) test
  • arity_shape on every op spec; Refusals (not fakes) for unhandled syntax; effects on the canonical Effect wire shapes, sorted
  • new ts-source lift surface (existing ts kit surface manifest untouched — the lesson from feat(csharp): add C# language lifter with RPC protocol and menagerie signature #590); version 0.1.0-draft
  • vitest 6/6 + full suite 785 tests pass; tsc --noEmit pass

🤖 Generated with Claude Code

…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>
Copilot AI review requested due to automatic review settings May 11, 2026 14:32
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 11, 2026

Warning

Rate limit exceeded

@TSavo has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 41 minutes and 51 seconds before requesting another review.

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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 616ebcc7-d5fb-4c18-a18d-22df2f14109b

📥 Commits

Reviewing files that changed from the base of the PR and between c9ba0c0 and 9db7904.

📒 Files selected for processing (80)
  • Makefile
  • implementations/rust/provekit-cli/src/project_config.rs
  • implementations/typescript/.provekit/lift/typescript-source/manifest.toml
  • implementations/typescript/src/lift/typescript-source/bin.ts
  • implementations/typescript/src/lift/typescript-source/index.test.ts
  • implementations/typescript/src/lift/typescript-source/index.ts
  • menagerie/typescript-language-signature/README.md
  • menagerie/typescript-language-signature/mint.sh
  • menagerie/typescript-language-signature/specs/eff_io.spec.json
  • menagerie/typescript-language-signature/specs/eff_opaque_loop.spec.json
  • menagerie/typescript-language-signature/specs/eff_panic.spec.json
  • menagerie/typescript-language-signature/specs/eff_read.spec.json
  • menagerie/typescript-language-signature/specs/eff_unresolved_call.spec.json
  • menagerie/typescript-language-signature/specs/eff_write.spec.json
  • menagerie/typescript-language-signature/specs/effsig_call.spec.json
  • menagerie/typescript-language-signature/specs/effsig_io.spec.json
  • menagerie/typescript-language-signature/specs/effsig_loop.spec.json
  • menagerie/typescript-language-signature/specs/effsig_panic.spec.json
  • menagerie/typescript-language-signature/specs/effsig_read.spec.json
  • menagerie/typescript-language-signature/specs/effsig_write.spec.json
  • menagerie/typescript-language-signature/specs/eq_seq_assoc.spec.json
  • menagerie/typescript-language-signature/specs/eq_seq_empty_left.spec.json
  • menagerie/typescript-language-signature/specs/eq_seq_empty_right.spec.json
  • menagerie/typescript-language-signature/specs/language_signature_typescript.spec.json
  • menagerie/typescript-language-signature/specs/op_add.spec.json
  • menagerie/typescript-language-signature/specs/op_and.spec.json
  • menagerie/typescript-language-signature/specs/op_args.spec.json
  • menagerie/typescript-language-signature/specs/op_assign.spec.json
  • menagerie/typescript-language-signature/specs/op_bitand.spec.json
  • menagerie/typescript-language-signature/specs/op_bitnot.spec.json
  • menagerie/typescript-language-signature/specs/op_bitor.spec.json
  • menagerie/typescript-language-signature/specs/op_bitxor.spec.json
  • menagerie/typescript-language-signature/specs/op_break.spec.json
  • menagerie/typescript-language-signature/specs/op_call.spec.json
  • menagerie/typescript-language-signature/specs/op_continue.spec.json
  • menagerie/typescript-language-signature/specs/op_decl.spec.json
  • menagerie/typescript-language-signature/specs/op_div.spec.json
  • menagerie/typescript-language-signature/specs/op_eq.spec.json
  • menagerie/typescript-language-signature/specs/op_for.spec.json
  • menagerie/typescript-language-signature/specs/op_ge.spec.json
  • menagerie/typescript-language-signature/specs/op_gt.spec.json
  • menagerie/typescript-language-signature/specs/op_if.spec.json
  • menagerie/typescript-language-signature/specs/op_index.spec.json
  • menagerie/typescript-language-signature/specs/op_ite.spec.json
  • menagerie/typescript-language-signature/specs/op_le.spec.json
  • menagerie/typescript-language-signature/specs/op_lt.spec.json
  • menagerie/typescript-language-signature/specs/op_member.spec.json
  • menagerie/typescript-language-signature/specs/op_mod.spec.json
  • menagerie/typescript-language-signature/specs/op_mul.spec.json
  • menagerie/typescript-language-signature/specs/op_ne.spec.json
  • menagerie/typescript-language-signature/specs/op_neg.spec.json
  • menagerie/typescript-language-signature/specs/op_new.spec.json
  • menagerie/typescript-language-signature/specs/op_not.spec.json
  • menagerie/typescript-language-signature/specs/op_nullish.spec.json
  • menagerie/typescript-language-signature/specs/op_or.spec.json
  • menagerie/typescript-language-signature/specs/op_pos.spec.json
  • menagerie/typescript-language-signature/specs/op_postdec.spec.json
  • menagerie/typescript-language-signature/specs/op_postinc.spec.json
  • menagerie/typescript-language-signature/specs/op_predec.spec.json
  • menagerie/typescript-language-signature/specs/op_preinc.spec.json
  • menagerie/typescript-language-signature/specs/op_return.spec.json
  • menagerie/typescript-language-signature/specs/op_seq.spec.json
  • menagerie/typescript-language-signature/specs/op_shl.spec.json
  • menagerie/typescript-language-signature/specs/op_shr.spec.json
  • menagerie/typescript-language-signature/specs/op_source-unit.spec.json
  • menagerie/typescript-language-signature/specs/op_sub.spec.json
  • menagerie/typescript-language-signature/specs/op_throw.spec.json
  • menagerie/typescript-language-signature/specs/op_typeof.spec.json
  • menagerie/typescript-language-signature/specs/op_ushr.spec.json
  • menagerie/typescript-language-signature/specs/op_while.spec.json
  • menagerie/typescript-language-signature/specs/sort_any.spec.json
  • menagerie/typescript-language-signature/specs/sort_args.spec.json
  • menagerie/typescript-language-signature/specs/sort_boolean.spec.json
  • menagerie/typescript-language-signature/specs/sort_expr.spec.json
  • menagerie/typescript-language-signature/specs/sort_lvalue.spec.json
  • menagerie/typescript-language-signature/specs/sort_null.spec.json
  • menagerie/typescript-language-signature/specs/sort_number.spec.json
  • menagerie/typescript-language-signature/specs/sort_stmt.spec.json
  • menagerie/typescript-language-signature/specs/sort_string.spec.json
  • menagerie/typescript-language-signature/specs/sort_unit.spec.json
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/typescript-source-lift-kit

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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, plus menagerie/manifest.yaml + Makefile wiring.
  • 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-source surface in the Rust CLI’s KNOWN_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");
Comment on lines +921 to +952
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.
Comment thread menagerie/manifest.yaml Outdated
- id: typescript-language-signature
path: typescript-language-signature
runnable: true
claim: TypeScript source AST operation algebra for ts:-namespaced function-contract mementos
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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 });
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

Comment on lines +375 to +376
const loopTerm = ctor("ts:for", init, cond, update, emitStatement(stmt.statement, context));
addEffect(context, { kind: "opaque_loop", loopCid: cidOfValue(loopTerm) });
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

@TSavo
Copy link
Copy Markdown
Owner Author

TSavo commented May 11, 2026

Review: PR #595feat(ts): TypeScript source lift kit (self-hosted, TS compiler API)

Verdict: MERGE-WITH-NITS — conformant, stricter-than-#590 (no ts:skip/ts:unknown catch-all, asserted by test), self-canonicalizing on the existing claimEnvelope/canonicalize.ts + canonicalizer/hash.ts (not a reinvention); the one substantive issue (round-trip test is tautological) is a test-strength gap, not a correctness bug.

What I verified (evidence)

  • node_modules/.bin/tsc --noEmit -p tsconfig.json → exit 0 (the new src/lift/typescript-source/ dir is covered by root tsconfig.json include).
  • vitest run implementations/typescript44 files, 785 pass + 4 todo (matches the "785 still pass" claim) + the new file → 6 pass.
  • RPC smoke under node --import tsx src/lift/typescript-source/bin.ts --rpc: initialize returns {name, version:"0.1.0-draft", protocol_version:"provekit-lift/1", capabilities:{authoring_surfaces:["typescript-source"], ir_version:"v1.1.0", emits_signed_mementos:false}}; lift on index.ts itself emits 3 ir entries + 69 refusals (loud, structured {kind,function,line,reason} — refuses async/generator/decorated/generic/rest/default/destructured, arrows, await, optional chaining, template literals, as/satisfies, function expressions); shutdownnull. ✅
  • Canonicalizer: index.ts:5-6 imports canonicalJsonString from claimEnvelope/canonicalize.ts (RFC-8785-ish sorted-keys/no-whitespace/UTF-8, the protocol-pinned one) and computeCid from canonicalizer/hash.ts (blake3-512, no truncation). No rolled-own JCS/BLAKE3.Supra omnia, rectum clear.
  • ts: prefix on every op spec; no ts:binop/ts:unknown/ts:skip catch-all. The default: arms in the lifter's emitStatement/emitExpression/binaryOperatorName all throw UnsupportedSyntaxError → refusal. ✅
  • arity_shape present on all 46 op specs and sane: binops named lhs/rhs; ts:and/ts:or/ts:nullish mark rhs evaluation:"unevaluated"; ts:ite marks then_expr/else_expr unevaluated; ts:seq/ts:args positional variadic; ts:assign named target/value; ts:if/ts:while/ts:for mark branch/body unevaluated; ts:source-unit named {bytes(unevaluated,literal), operational_term}. Mirrors the c11/csharp op-spec shape. ✅
  • ts:source-unit(bytes, operational_term) op present (op_source-unit.spec.json) and emitted by the lifter carrying sourceFile.getFullText() (index.ts:210, sourceUnitContract :650). Test index.test.ts:33-36 confirms. ✅
  • fnName = <module-path>:<qualified-name> from AST prefix path ([...prefix, shortName].join("."), :285). Overloads can't collide: overload signatures are bodyless → refused (:237-238); only the implementation (with body) is lifted. Class vs namespace funcs are disambiguated by prefix (N.A.m vs N.m). Built syntactically, not via TypeChecker symbol — adequate for the supported slice but see nit (4).
  • Effects on canonical wire shapes: reads/writes with target, io, panics, unresolved_call with name, opaque_loop with loopCid:"blake3-512:...". No alloc, no resolved-call (resolved calls in knownCallables emit no effect — :517-518). effectSortKey uses prefixes 0:reads 1:writes 2:io 4:panics 5:unresolved_call 6:opaque_loop — numeric prefixes match Rust libprovekit/src/compose.rs:241-247 (Effect::sort_key); the 5:unresolved_call:name vs Rust's 5:unresolved:name differs only in the throwaway sort string, not the emitted value or array order. Test index.test.ts:69-97 asserts the exact array. ✅
  • Determinism: emitted JSON via the shared canonicalizer (sorted keys, no whitespace); effects sorted before emit; no Map-iteration leak (effects collected in a Map keyed by sort-key, then [...values()].sort(effectSortKey)); no timestamps. ✅
  • Wiring: existing implementations/typescript/.provekit/lift/typescript/manifest.toml not repointed (still npx tsx src/lift/bin/main.ts --rpc) ✅. New typescript-source surface manifest added; typescript-source added to KNOWN_SURFACES (project_config.rs:208) + unit-test assertion. version 0.1.0-draft. No .provekit/ci/accepted/* / self-contract-pin changes (expected for draft). ✅
  • The compile RPC method is non-standard (the protocol spec only defines initialize/lift/shutdown) — but feat(csharp): add C# language lifter with RPC protocol and menagerie signature #590's C# lifter does the same (RpcServer.cs/CsharpCompiler.cs, initialize, lift, compile, shutdown), so this is an established extension, not a feat(ts): add TypeScript source lift kit (self-hosted) + ts-language-signature #595 regression.

One thing to look at first

The round-trip test is tautological. compileTypeScriptSourceIr (index.ts:165-189) — when a <source-unit> is present, returns its stored raw source-bytes string (:168-177). The lifter always prepends a <source-unit> whenever lifted.length > 0 (:209-211). So lift(compile(lift(src))) exercises only the byte-copy path; the compileFunctionContract/ts.createPrinter AST-emit path (:179-189, :901-1022) is dead code under normal use (only reachable if a caller hands compile an IR doc with no source-unit). The test name "round-trips lift(compile(lift(src))) with byte-identical canonical IR" overpromises. Not a bug — the lossless source-bytes wrapper is the intentional design — but the test isn't proving the AST printer is byte-stable. Add a hand-crafted-IR-without-source-unit round-trip case, or rename the test. Non-blocking.

Blocking findings

None.

Non-blocking nits

  1. Tautological round-trip test (above) — implementations/typescript/src/lift/typescript-source/index.test.ts:118-135.
  2. menagerie/manifest.yaml:32-36 registers typescript-language-signature as a runnable destination — inconsistent with established precedent: c11-language-signature, rust-language-signature, aarch64-language-signature, jvm-bytecode-language-signature, and the just-merged csharp-language-signature are not registered there. Arguably an improvement; if kept, file a follow-up to register the others (or drop this entry to match).
  3. menagerie/typescript-language-signature/mint.sh uses find to enumerate specs; c11/rust mint.sh do not (they enumerate explicitly / via a generator). Style/portability nit.
  4. hasUnsupportedFunctionShape collapses six distinct refusal reasons into one message string (index.ts:288) — a caller can't tell which unsupported shape triggered it. Minor UX; consider splitting.
  5. Draft kit not yet minted: no cids.tsv / catalog/ / component-cids.json checked in (c11/rust have them), README is a 5-line stub. Expected for 0.1.0-draft; file a follow-up to mint + pin (and add a make smoke or CICP leg) before it leaves draft.
  6. EPERM note: the existing typescript manifest uses npx tsx ...; the new typescript-source manifest also uses ["npx","tsx","src/lift/typescript-source/bin.ts","--rpc"]. The agent's node --import tsx form worked in my sandbox; npx tsx is the established form and presumably works in CI — but if the EPERM recurs in the runner, this manifest will inherit it. Worth confirming the CICP run is green before merge.

Conformance checklist

# 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 ⚠️ test passes but exercises only the byte-copy path; AST-printer path untested (nit 1)
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>
@TSavo TSavo merged commit 5b2f45b into main May 11, 2026
18 checks passed
TSavo added a commit that referenced this pull request May 12, 2026
…#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>
TSavo added a commit that referenced this pull request May 12, 2026
…#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>
TSavo added a commit that referenced this pull request May 12, 2026
…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>
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