Skip to content

feat(ts): wire --kit=ts to typescript-self-contracts surface + RPC mode (closes #204)#220

Merged
TSavo merged 1 commit into
mainfrom
fix/cmd-mint-kit-ts-surface
May 4, 2026
Merged

feat(ts): wire --kit=ts to typescript-self-contracts surface + RPC mode (closes #204)#220
TSavo merged 1 commit into
mainfrom
fix/cmd-mint-kit-ts-surface

Conversation

@TSavo
Copy link
Copy Markdown
Owner

@TSavo TSavo commented May 4, 2026

Summary

  • Wire --kit=ts to a new typescript-self-contracts lift surface by changing the KIT_TABLE entry surface from "typescript" to "typescript-self-contracts"
  • Add implementations/typescript/src/bin/mint-ts-self-contracts-rpc.cjs: CJS RPC shim that speaks the lift-plugin protocol (provekit-lift/1) over NDJSON; uses node --experimental-require-module + tsx/cjs to handle ESM-only @ipld/dag-cbor through the tsx CJS transform bridge
  • Add implementations/typescript/.provekit/lift/typescript-self-contracts/manifest.toml: surface manifest; command ["node", "--experimental-require-module", "src/bin/mint-ts-self-contracts-rpc.cjs"]
  • Add Test 8 ts_kit_pins_expected_contract_set_cid pinning TS_CONTRACT_SET_CID (69 contracts, 14 slabs); prevents regression to the empty-set sentinel
  • Update .provekit/self-contracts-attestations/ts.json with the real contractSetCid

Key technical detail

@ipld/dag-cbor is ESM-only. The existing tsx CJS bridge (npx tsx) fails on Node 25 because the .mts extension forces ESM module mode, but the compiled project targets CJS. The solution: node --experimental-require-module (Node 22+) allows require() of ESM modules; combined with tsx/cjs for TypeScript transpilation, the CJS RPC shim loads and runs the full runMintSelfContracts() orchestrator correctly.

Test plan

  • make mint-ts succeeds; contractSetCid = blake3-512:5a45314f... (content-meaningful, not d53d18c2... empty-set)
  • 54 Rust unit tests pass (cargo test --bin provekit)
  • 775 TypeScript tests pass (pnpm vitest run)
  • RPC handshake smoke-tested: initialize/lift/shutdown via stdin pipe
  • .provekit/self-contracts-attestations/ts.json updated with real CID

🤖 Generated with Claude Code

…de (closes #204)

- Add `implementations/typescript/src/bin/mint-ts-self-contracts-rpc.cjs`:
  CJS RPC shim that speaks the lift-plugin protocol (provekit-lift/1) over
  NDJSON on stdio. Uses `node --experimental-require-module` + `tsx/cjs` to
  import ESM-only @ipld/dag-cbor through the tsx CJS transform bridge.
  Implements initialize/lift/shutdown; treats stdin EOF as graceful shutdown.

- Add `implementations/typescript/.provekit/lift/typescript-self-contracts/manifest.toml`:
  Declares the typescript-self-contracts surface. Command:
  `["node", "--experimental-require-module", "src/bin/mint-ts-self-contracts-rpc.cjs"]`
  working_dir = "." (implementations/typescript).

- Update KIT_TABLE in `implementations/rust/provekit-cli/src/cmd_mint.rs`:
  `ts` entry surface changed from "typescript" to "typescript-self-contracts".
  Fixes the routing so `--kit=ts` reaches the self-contracts lifter, not the
  generic workspace lifter that produced the empty-set CID.

- Fix `resolve_kit_ts_maps_to_typescript_dir` unit test to assert the new
  surface name.

- Add Test 8 `ts_kit_pins_expected_contract_set_cid` to
  `implementations/rust/provekit-cli/tests/mint_kit_integration.rs`:
  Pins TS_CONTRACT_SET_CID = blake3-512:5a45314f... (69 contracts, 14 slabs).

- Update `.provekit/self-contracts-attestations/ts.json` with the real
  contractSetCid (previously the empty-set sentinel d53d18c2...).

Verified: `make mint-ts` succeeds; contractSetCid is content-meaningful
(5a45314f...), not the empty-set sentinel. 775 TS tests pass; 54 Rust
unit tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 4, 2026 03:06
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 4, 2026

Warning

Rate limit exceeded

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

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ 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: 5bb03d2a-d44f-4ab5-9e7f-e5e9b21b0e2c

📥 Commits

Reviewing files that changed from the base of the PR and between 5234de0 and aa1c434.

📒 Files selected for processing (5)
  • .provekit/self-contracts-attestations/ts.json
  • implementations/rust/provekit-cli/src/cmd_mint.rs
  • implementations/rust/provekit-cli/tests/mint_kit_integration.rs
  • implementations/typescript/.provekit/lift/typescript-self-contracts/manifest.toml
  • implementations/typescript/src/bin/mint-ts-self-contracts-rpc.cjs
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/cmd-mint-kit-ts-surface

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
Review rate limit: 0/1 reviews remaining, refill in 10 minutes and 33 seconds.

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

This PR updates the Rust CLI’s --kit=ts routing so that TypeScript minting uses a dedicated typescript-self-contracts lift surface via an RPC shim, and pins the resulting contract set CID to prevent regressions back to the empty-set sentinel.

Changes:

  • Route --kit=ts to the new typescript-self-contracts surface in KIT_TABLE (and update the resolver unit test accordingly).
  • Add a TypeScript self-contracts lift-plugin manifest and a CJS JSON-RPC (NDJSON) shim that returns the proof-envelope response shape.
  • Add a Rust integration test pinning the expected TS contractSetCid and update the checked-in TS self-contracts attestation.

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
implementations/typescript/src/bin/mint-ts-self-contracts-rpc.cjs New JSON-RPC/NDJSON entrypoint that runs runMintSelfContracts() and returns a proof-envelope payload.
implementations/typescript/.provekit/lift/typescript-self-contracts/manifest.toml New surface manifest pointing the Rust CLI at the TypeScript self-contracts RPC shim.
implementations/rust/provekit-cli/tests/mint_kit_integration.rs Adds a TS contractSetCid pinning integration test.
implementations/rust/provekit-cli/src/cmd_mint.rs Wires --kit=ts to typescript-self-contracts and updates the resolve test.
.provekit/self-contracts-attestations/ts.json Updates the pinned TS cid and contractSetCid (and signature) to the newly minted values.
Comments suppressed due to low confidence (1)

implementations/rust/provekit-cli/tests/mint_kit_integration.rs:534

  • The section header for the C++ pinning test is still labeled "Test 8" even though the new TypeScript test is also labeled "Test 8". Renumber the C++ header (and any subsequent headers) to keep the test index comments unambiguous.
// ---------------------------------------------------------------------------
// Test 8: cpp kit contractSetCid is pinned to the canonical self-contracts CID
//         (issue #203 regression gate, PR wiring cpp-self-contracts surface)
// ---------------------------------------------------------------------------

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

name = "typescript-self-contracts"
version = "1.0.0"
protocol_version = "provekit-lift/1"
command = ["node", "--experimental-require-module", "src/bin/mint-ts-self-contracts-rpc.cjs"]
@TSavo TSavo merged commit 3b2e658 into main May 4, 2026
8 checks passed
TSavo added a commit that referenced this pull request May 4, 2026
…closes #211)

Side A substrate-conformance work for the swift kit. Two related changes,
both required for issue #211 acceptance:

1. SwiftSyntax-based lifter (Path B): replaces regex-v0 in
   `SwiftLifter.swift` with a real AST walker using Apple's official
   swift-syntax 600.x library. The wire shape (declarations, callEdges,
   warnings) is byte-preserved; LSPTests' 11 integration tests pass
   unmodified. Adds InitializerDeclSyntax handling (regex-v0 never
   matched `init`); the addition is additive and downstream-safe.

2. swift-self-contracts lift surface + RPC mode (Path A): mirrors the
   PR #220 daemon-lifecycle pattern (ts Side A) and PR #217 (cpp Side A
   wiring). The swift mint binary now speaks the lift-plugin protocol
   over NDJSON-on-stdio: initialize -> lift (proof-envelope shape) ->
   shutdown, with stdin-EOF graceful exit per architect rule #3.

   * `MintSwiftSelfContracts/main.swift`: thin entry-point that branches
     on `--rpc` argv. Slab moved to `Slab.swift`; RPC handlers in
     `RPC.swift`. SPM compiles all three into one module.
   * `Slab.swift`: pure function `swiftSelfContracts() -> [Declaration]`
     authoring all 11 lift-plugin-protocol contracts (C1-C8, 11 facets),
     callable from both human and RPC entry points.
   * `RPC.swift`: NDJSON loop; `handleLift` walks the slab, computes
     content-meaningful CIDs, emits a proof-envelope.
   * `.provekit/lift/swift-self-contracts/manifest.toml`: declares
     surface + capabilities + binary path. Mirrors the ts/go/cpp peers.
   * `cmd_mint.rs`: KIT_TABLE swift entry routes to swift-self-contracts.

Cross-kit IR byte-equality (per dispatch directive):
- contractSetCid: byte-equivalent. Computed via the canonical formula
  blake3_512(JCS(sorted([contract_cid(c) for c in slab]))) where each
  contract_cid = blake3_512(JCS({name, outBinding, pre?, post?, inv?})),
  matching `provekit-claim-envelope::contract_cid` and
  `provekit-claim-envelope::compute_contract_set_cid` exactly.
- proof-envelope bytes: NOT byte-equivalent. The swift kit emits a
  JCS-JSON catalog with self-identifying `kind:
  "swift-self-contracts-catalog-phase3-pending"` rather than the
  cross-kit CBOR-signed catalog. This is consistent with the existing
  Phase 3 deferral noted in `MintSwiftSelfContracts/main.swift:208-211`
  (now `main.swift:46-48`); a follow-up PR can land the full CBOR +
  Ed25519 envelope (mirroring PR #221 for python). The dispatcher only
  requires `kind:"proof-envelope"`, non-empty `filename_cid`, and
  decodable `bytes_base64` — all satisfied. The filename_cid changes
  whenever the slab changes, satisfying acceptance gate #2.

Acceptance gate #4 ("provekit prove --kit=swift exits 0"): provekit
prove doesn't accept --kit (see `provekit-cli/src/main.rs:119`); the
intent is read as "mint pipeline succeeds end-to-end on macOS." `make
mint-swift` runs cleanly and `verify-self-contracts` returns OK against
the new attestation, demonstrating the full pipeline.

- [x] `swift run conformance` (10/10 PASS)
- [x] `swift run test-swift-lsp` (11/11 PASS — wire shape preserved)
- [x] `swift run mint-swift-self-contracts` human mode (CID matches)
- [x] `mint-swift-self-contracts --rpc` direct subprocess (initialize/lift/shutdown trip)
- [x] `cargo test cmd_mint` (9/9 unit tests pass)
- [x] `cargo test mint_kit_integration swift_kit_pins_expected_contract_set_cid` (PASS)
- [x] `make mint-swift` end-to-end: contractSetCid pinned, attestation OK
- [x] Three independent paths agree on contractSetCid blake3-512:272543ef...

- swift contractSetCid: blake3-512:272543efe7c47b911659e1fc6a7368431b6eaa6010d2560a5d3e6717fcd470b50b24b607b481272941764b731d890d6973ab88e6000bde96fd306163a5742c56

Pre-existing test failures unrelated to #211: rust/cpp self-contracts
binaries are not built in this worktree, causing
`rust_kit_contract_set_cid_is_pinned_to_self_contracts_canonical` and
`cpp_kit_contract_set_cid_is_pinned_to_self_contracts_canonical` to
fall back to empty-set CIDs. Not a regression introduced by #211.

Closes #211.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
TSavo added a commit that referenced this pull request May 4, 2026
…ing (closes #205)

Side A bootstrap for the Python kit per issue #176. The orchestrator
walks the canonical Python slab (5 slabs of 3 contracts each, 15
total: blake3 / jcs / cbor / signing / proof_envelope), mints each
contract as a v1.2 layered signed memento under the foundation key,
and bundles them into a `.proof` envelope whose filename IS its
catalog CID. The KIT_TABLE flip routes `--kit=python` from the
placeholder `python` surface to the new `python-self-contracts`
surface, mirroring the rust / go / cpp / ts / ruby wiring pattern
(PRs #180, #183, #217, #220, #234).

The orchestrator imports the python claim-envelope substrate that
landed in PR #232 (`ClaimEnvelope.from_contract_decl`,
`compute_contract_set_cid`) plus the proof-envelope crypto primitives
from PR #221 (`build_proof_envelope`, `Signer.foundation_v0`,
`ed25519_pubkey_string`, `blake3_512_of`); no reimplementation. Unlike
the ruby PR #234, no inline `mint_contract` port was needed because
the python lib already exposes the full layered-mint API.

The `--rpc` mode follows the daemon-lifecycle pattern PR #220
established: persistent NDJSON stdio loop, EOF on stdin = graceful
shutdown, explicit `shutdown` method acks then exits, JSON-RPC error
objects on parse / method-not-found / lift-failed without crashing.

- [x] Orchestrator (`provekit-self-contracts.py` + bin shim
      `bin/mint-python-self-contracts`) walks the python slab, calls
      `ClaimEnvelope.from_contract_decl`, builds proof envelope via
      existing primitives.
- [x] Speaks the canonical `--rpc` lift-protocol, emits proof-envelope
      to stdout with `kind`, `filename_cid`, `contract_set_cid`,
      `bytes_base64`, `diagnostics`.
- [x] Add `python-self-contracts` lift surface manifest at
      `implementations/python/.provekit/lift/python-self-contracts/manifest.toml`.
- [x] Update `KIT_TABLE` in `implementations/rust/provekit-cli/src/cmd_mint.rs`
      python entry surface from `"python"` to `"python-self-contracts"`.
- [x] Add a pinned-CID test (`python_kit_pins_expected_contract_set_cid`)
      in `mint_kit_integration.rs`. Move `python` from
      `KITS_WITHOUT_LIFTERS` to `KITS_WITH_LIFTERS` AND
      `KITS_WITH_REAL_CONTRACTS`.
- [x] `make mint-python` produces a content-meaningful contractSetCid
      (`blake3-512:b1de9417...`), not the empty-set sentinel.
- [x] `provekit prove implementations/python` exits 0.
- [x] Pinned-CID test passes.
- [x] LSP daemon lifecycle is explicit (no orphan processes after the
      run): EOF on stdin or explicit `shutdown` returns 0.

```rust
// before
("python",     "python",      "python",                "python"),
// after
("python",     "python",      "python-self-contracts", "python"),
```

```
>> minting python self-contracts
  cid:            blake3-512:64c8ddf3a7ef02c6d12665866e1c2483b59009830a5f27cee869b123d5ece63cccb7dc8d62002383f348b15cd866857de0c6a053dd2fc02e3d9356bd3295b0a4
  contractSetCid: blake3-512:b1de941756d0a3b352ca79ebed8b75644b7c782c3afe4163273220384125ec100457d5e969a921b7ceb277e329a24c5a4ea21ffd54963b51c1756befdb1793dc
OK  .provekit/self-contracts-attestations/python.json (contractSetCid blake3-512:b1de941756d0a3b352ca79ebed8b75644b7c782c3afe4163273220384125ec100457d5e969a921b7ceb277e329a24c5a4ea21ffd54963b51c1756befdb1793dc)
```

The catalog CID and contractSetCid are byte-deterministic across two
consecutive mint runs (orchestrator's built-in determinism check, plus
the rust integration test).

- Persistent NDJSON stdio loop (one process serves multiple `lift` calls).
- `initialize` returns the protocol version, plugin name, and capabilities.
- `lift` returns the `proof-envelope` shape with base64-encoded bytes.
- `shutdown` writes the ack response and exits 0.
- EOF on stdin = graceful shutdown (loop exit returns 0).
- Errors emit JSON-RPC error objects (`-32700` parse, `-32601`
  method-not-found, `1005` LIFT_FAILED) without crashing the process.

- [x] Direct CLI smoke (`python3 implementations/python/bin/mint-python-self-contracts /tmp/...`):
      passes; deterministic across runs.
- [x] RPC smoke (initialize / lift / shutdown over stdin pipe): all
      three responses well-formed.
- [x] `provekit mint --kit=python --quiet` (via the dispatcher):
      passes; emits the same `cid` / `contractSetCid`.
- [x] `cargo test --release -p provekit-cli --test mint_kit_integration python_kit_pins_expected_contract_set_cid`:
      passes.
- [x] `cargo test --release -p provekit-cli --test mint_kit_integration all_kits_mint_produces_valid_attestation_structure`:
      passes (python now in `KITS_WITH_LIFTERS` + `KITS_WITH_REAL_CONTRACTS`).
- [x] `provekit prove implementations/python`: exit 0.
- [x] All 143 pre-existing python pytest suites in
      `implementations/python/provekit-lift-py-tests/`: pass.

- **Import path**: the bin shim prepends
  `provekit-lift-py-tests/src` to `sys.path` so the orchestrator
  works without `pip install -e .` (the `mint-python` Makefile target
  has no `build-python` dependency, unlike `test-python`). The
  orchestrator self-injects too as belt-and-suspenders.
- **Python wheels**: `blake3`, `pynacl`, `cbor2` are declared
  dependencies of `provekit-lift-py-tests` and are installed in CI
  via `make test-python`'s `pip install -e .`. The pinned-CID test
  skips on toolchain failure (mirrors ruby/cpp/ts), so a missing
  wheel surfaces as test-skip rather than test-fail.
- **No em-dashes** per CLAUDE.md: the docstrings and commit message
  use commas and parentheses.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
TSavo added a commit that referenced this pull request May 4, 2026
…loses #209)

Side A bootstrap for the Ruby kit per issue #176. Walks the canonical Ruby
slab (5 slabs, 15 contracts about blake3 / jcs / cbor / signing /
proof_envelope), mints each as a layered signed memento under the
foundation key (test seed [0x42; 32]), and bundles the result into a
.proof envelope whose filename IS its catalog CID.

The orchestrator is wireable through the rust CLI's `--kit=ruby` flow via
the new lift surface manifest, then drives the canonical mint-and-attest
pipeline (lift-protocol RPC over NDJSON-on-stdio, persistent daemon-with-
explicit-shutdown lifecycle per PR #220 ts Side A).

Components:
- implementations/ruby/lib/provekit/self_contracts.rb — orchestrator with
  slab authoring, contractCid + contractSetCid + layered-memento mint
  (port of provekit-claim-envelope `mint_contract`), proof-envelope
  bundling, byte-determinism check, and `--rpc` mode.
- implementations/ruby/bin/mint-ruby-self-contracts — entry point used by
  the lift surface manifest. Re-execs under Homebrew ruby (>= 3.0) when
  launched on the macOS system ruby.
- implementations/ruby/.provekit/lift/ruby-self-contracts/manifest.toml —
  lift surface manifest declaring the RPC command, capabilities, and
  ir_version.
- implementations/rust/provekit-cli/src/cmd_mint.rs — KIT_TABLE flip
  routing `--kit=ruby` from `ruby` to `ruby-self-contracts` (mirrors the
  rust/go/cpp/ts pattern from PR #180/#183/#217/#220).
- implementations/rust/provekit-cli/tests/mint_kit_integration.rs —
  pinned-CID test for ruby plus list updates moving ruby out of
  KITS_WITHOUT_LIFTERS into KITS_WITH_LIFTERS / KITS_WITH_REAL_CONTRACTS.
- .provekit/self-contracts-attestations/ruby.json — re-minted under the
  new orchestrator (now content-meaningful, no longer the empty-set
  sentinel).

`make mint-ruby` produces:
  cid:            blake3-512:6358ad54d0535d87be144d765127b7dcdde7fa6d807e27b8d85f4d3549609cd7fb573a711e7668152339753398c68dbb5e23dc2e0083ca5e7dc2c00e439d69da
  contractSetCid: blake3-512:961be80d8a5ae8f3d8255462fc1845d5b45f30c0b4412c9d8b354078d63096ba363b6ae0dea4f2e35141213dc5c6b855156f434b5620a345bfbc20725bee00ff

`provekit prove implementations/ruby` exits 0. The new
`ruby_kit_pins_expected_contract_set_cid` integration test passes;
existing ruby unit tests under `implementations/ruby/test/` continue to
pass on Homebrew ruby 3.x.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
TSavo added a commit that referenced this pull request May 4, 2026
…ring (closes #213)

Side A (substrate-driven conformance) for the zig kit: 14 canonical
contracts across 6 slabs (jcs, hash, sign, cbor, proof-envelope,
lift-plugin-protocol) authoring the kit's own crypto+canonicalization
surface. The orchestrator computes spec #94 §1 contractCids +
contractSetCid, builds a .proof envelope via the just-landed Side B
substrate (PR #227), and speaks the lift-plugin-protocol over NDJSON
on stdio in --rpc mode.

Daemon-lifecycle: persistent-daemon-with-explicit-shutdown per PR #220.
Stdin EOF -> graceful exit 0; explicit shutdown method replies then
exits 0; lift remains the loop body, not a one-shot.

Tier-3 bootstrap shape: members map is empty pending a future port
of claim-envelope to zig (no signed-memento minting yet). The
contractSetCid is content-meaningful regardless and is the cross-kit
conformance anchor under spec #94 §1.

Acceptance:
- [x] zig slab with canonical contracts (14 contracts, 6 slabs)
- [x] mint-zig-self-contracts orchestrator
- [x] --rpc lift-protocol speaker, proof-envelope on stdout
- [x] manifest at implementations/zig/.provekit/lift/zig-self-contracts/
- [x] KIT_TABLE: zig -> zig-self-contracts surface
- [x] pinned-CID test in mint_kit_integration.rs
- [x] make mint-zig produces content-meaningful contractSetCid
      (blake3-512:405ff171...20e93e3, 14-contract canonical set)
- [x] provekit prove implementations/zig exits 0
- [x] zig moved from KITS_WITHOUT_LIFTERS to KITS_WITH_LIFTERS +
      KITS_WITH_REAL_CONTRACTS

Boy-scout: cpp pinning test now skips cleanly when lifter binary
isn't built (matches the empty-set-CID short-circuit pattern used
elsewhere). Same skip pattern applied to
kits_with_real_contracts_produce_nonempty_contract_set.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
TSavo added a commit that referenced this pull request May 4, 2026
…ring (closes #213)

Side A (substrate-driven conformance) for the zig kit: 14 canonical
contracts across 6 slabs (jcs, hash, sign, cbor, proof-envelope,
lift-plugin-protocol) authoring the kit's own crypto+canonicalization
surface. The orchestrator computes spec #94 §1 contractCids +
contractSetCid, builds a .proof envelope via the just-landed Side B
substrate (PR #227), and speaks the lift-plugin-protocol over NDJSON
on stdio in --rpc mode.

Daemon-lifecycle: persistent-daemon-with-explicit-shutdown per PR #220.
Stdin EOF -> graceful exit 0; explicit shutdown method replies then
exits 0; lift remains the loop body, not a one-shot.

Tier-3 bootstrap shape: members map is empty pending a future port
of claim-envelope to zig (no signed-memento minting yet). The
contractSetCid is content-meaningful regardless and is the cross-kit
conformance anchor under spec #94 §1.

Acceptance:
- [x] zig slab with canonical contracts (14 contracts, 6 slabs)
- [x] mint-zig-self-contracts orchestrator
- [x] --rpc lift-protocol speaker, proof-envelope on stdout
- [x] manifest at implementations/zig/.provekit/lift/zig-self-contracts/
- [x] KIT_TABLE: zig -> zig-self-contracts surface
- [x] pinned-CID test in mint_kit_integration.rs (uses ScratchRepo
      pattern from #250; skips cleanly when zig binary unavailable
      or empty-set-CID returned)
- [x] make mint-zig produces content-meaningful contractSetCid
      (blake3-512:405ff171...20e93e3, 14-contract canonical set)
- [x] provekit prove implementations/zig exits 0
- [x] zig moved from KITS_WITHOUT_LIFTERS to KITS_WITH_LIFTERS +
      KITS_WITH_REAL_CONTRACTS

Boy-scout: cpp pinning test now skips cleanly when lifter binary
isn't built (matches the empty-set-CID short-circuit pattern used
elsewhere). Same skip pattern applied to
kits_with_real_contracts_produce_nonempty_contract_set.

Boy-scout (caught during rebase): convert c_kit_pins_expected_contract_set_cid
and ruby_kit_pins_expected_contract_set_cid to the ScratchRepo pattern.
PRs #272 (c) and #234 (ruby) merged with the old run_mint("kit") /
repo_root() signature after #250 changed run_mint to take (root, kit) +
introduced ScratchRepo, leaving main with a compile error. Also moved
the EMPTY_SET_CID guard before the pin assert (mirrors cpp/swift) so
test environments without those lifters built skip cleanly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ConstCorrectness pushed a commit to ConstCorrectness/provekit that referenced this pull request May 6, 2026
…KIT_TABLE wiring (closes TSavo#207)

New Maven module `provekit-java-self-contracts` under `implementations/java/`
provides the Side A substrate-driven conformance for the java kit per the
(A)/(B) split (TSavo#176). Imports the just-landed `provekit-claim-envelope`
(TSavo#208 / PR TSavo#228) for native BLAKE3 + JCS + Ed25519 + CBOR + envelope
construction; no shell-out to another kit.

## Module shape

- `Slab.java`: minimal in-module Collector + ContractDecl + JCS-Value
  formula DSL (var/const/ctor/atomic/forall/eq/gte/startsWith). Avoids
  building an authoring surface in `provekit-ir`; the bootstrap doesn't
  need one and rust hasn't lifted that surface yet.
- `JavaKitInvariants.java`: 6 slabs (blake3, cbor, claim_envelope,
  ed25519, jcs, proof_envelope), 30 `java_*`-prefixed contracts.
  Mirrors the cross-kit pattern (csharp `*Invariants.Register()`, rust
  `.invariant.rs` + orchestrator `#[path]`).
- `Orchestrator.java`: drains every slab, mints each contract via
  `ClaimEnvelope.mintContract`, builds the catalog via
  `ProofEnvelope.build`, computes `contractSetCid` with
  `ClaimEnvelope.computeContractSetCid`. Mirrors the C# `Program.MintOneRun`
  flow line-for-line.
- `Rpc.java`: lift-plugin protocol (`provekit-lift/1`) on stdio NDJSON.
  Persistent daemon (handles initialize/lift/N times/shutdown), only
  exits on shutdown. Matches the daemon-lifecycle pattern established
  by PR TSavo#220 (ts) and the csharp peer.
- `Main.java`: arg parse: `--rpc` -> Rpc.run(); else Orchestrator.runCli().
- `run-rpc.sh`: shell wrapper resolving java via `$JAVA`, `$JAVA_HOME`,
  `$PATH`, then Homebrew openjdk fallback (the macOS `/usr/bin/java`
  stub refuses to run when no JDK is registered in
  `/Library/Java/JavaVirtualMachines/`; we bypass it).
- Shaded jar via `maven-shade-plugin` (BouncyCastle + claim-envelope
  bundled, BC signature files stripped so verification doesn't reject
  the relocated classes).

## Acceptance (TSavo#207)

- [x] Maven module created, parent reactor updated.
- [x] Module walks the kit's own contracts via JavaKitInvariants slabs.
- [x] Emits proof-envelope to stdout under canonical `--rpc` framing.
- [x] Lift surface manifest at `implementations/java/.provekit/lift/java-self-contracts/manifest.toml`.
- [x] KIT_TABLE updated: `("java", "java", "java", "java")` -> `("java", "java", "java-self-contracts", "java")`.
- [x] Pinned-CID test 9 in `mint_kit_integration.rs`; java moved from KITS_WITHOUT_LIFTERS to KITS_WITH_LIFTERS.
- [x] `make mint-java` produces `contractSetCid: blake3-512:a22c9736...` (content-meaningful, not the empty-set sentinel `d53d18c2...`).
- [x] `provekit prove implementations/java` exits 0.
- [x] `mvn test` for the module: 5 passing (smoke tests for mint determinism + slab structure).

## mint-java output

```
catalog cid:    blake3-512:93dd048300ce9db0454fae4dd9639deca7d200de2edc005672213aec492e75c95c342ad174e3850e8ec31cfe09403c8f772fafff778254ea246367648b3a0e39
contractSetCid: blake3-512:a22c97362e15faf1e848eeb7d668ba50eba8cfb851a72465f2cccb0ca9e12af198ec14cc0e65453a18b1e40bbd17497f8975b6e3625bbf2b6b31e6ca6aacb6e3
30 contracts across 6 slabs
```

## KIT_TABLE diff

```
-    ("java",       "java",        "java",                 "java"),
+    ("java",       "java",        "java-self-contracts",  "java"),
```

## Daemon-lifecycle adherence

`Rpc.run()` reads NDJSON in a `while (line = readLine())` loop, dispatching
`initialize`/`lift`/`shutdown`. Only `shutdown` returns from the loop;
`initialize` and `lift` may be called any number of times before
shutdown. Each `lift` mints into a fresh `Files.createTempDirectory`
that's cleaned up before the response is emitted. Matches PR TSavo#220's
"persistent-daemon-with-explicit-shutdown" contract.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 (1M context) <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