Skip to content

feat(767): mint-plugin-cid binary + java-canonical-bodies.json with real CID#767

Merged
TSavo merged 1 commit into
mainfrom
feat/767-mint-plugin-cid
May 13, 2026
Merged

feat(767): mint-plugin-cid binary + java-canonical-bodies.json with real CID#767
TSavo merged 1 commit into
mainfrom
feat/767-mint-plugin-cid

Conversation

@TSavo
Copy link
Copy Markdown
Owner

@TSavo TSavo commented May 13, 2026

Why

First implementation PR after #766 (body-template-memento spec) merged. Closes the §4 "MUST be content-addressed" requirement honestly, instead of the literal PLACEHOLDER_TO_BE_MINTED_FROM_JCS_OF_CONTENT that sank #765.

What

1. mint-plugin-cid binary — the missing recipe artifact

implementations/rust/provekit-plugin-loader/src/bin/mint_plugin_cid.rs — reuses compute_plugin_cid (already in the plugin-loader crate, already specced in 2026-05-12-plugin-protocol.md §6.1) and exposes it as a CLI.

Verified against slice 2: running mint-plugin-cid on the EXISTING menagerie/java-language-signature/specs/sugar/java-canonical.json reproduces its pinned blake3-512:b7ad1160... exactly. This is the recipe slice 2 used; it was always in compute_plugin_cid (JCS over the full header sans cid, BLAKE3-512), but there was no entrypoint to call it on a file.

2. java-canonical-bodies.json with REAL minted CID

Three v1.0.0 entries per 2026-05-13-body-template-memento.md §2:

concept_name template signature_guard
identity return ${param0}; 1 param
bool-cell return !${param0}; 1 param
unit return; (void) 0 params

Header CID: blake3-512:a059900f182649c9bfbefdbc2a87931d185736cef1567cb71e625a29a7931a9dcc4c9b8cd07fa8ea8931056eae1586bc3610a37ce9be591ef5f4ec2d73de6a51.

provenance_cid + envelope signature use the all-zeros sentinel (same v0 pattern as slice 2's java-canonical.json). Substrate-wide sentinel convention; real provenance signing tracked separately.

3. Drift-prevention test

provekit-plugin-loader/tests/substrate_default_cids.rs asserts for each substrate default plugin file:

  • declared header.cid == what compute_plugin_cid recomputes (catches edits without re-minting),
  • declared header.cid == pinned-in-test value (catches recipe-side drift).

Covers java-canonical.json (slice 2) + java-canonical-bodies.json (new). Future default plugins just add another #[test].

This guard is exactly what was missing on #765: PR #765's JSON shipped with the literal PLACEHOLDER_TO_BE_MINTED_FROM_JCS_OF_CONTENT string where the CID should have been, and nothing failed CI. With this test in place, that can't happen again.

Tests

  • substrate_default_cids::java_canonical_sugar_cid_self_consistent: PASS (re-mints slice 2's CID)
  • substrate_default_cids::java_canonical_bodies_cid_self_consistent: PASS (re-mints new CID)
  • Full provekit-plugin-loader regression: all green (17 + 9 + 2 + smaller groups, zero failures)

Gated by

#766 (body-template-memento spec, merged at fe1f06b). This PR is the spec's first consumer.

Blocks

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a command-line tool to compute and verify content identifiers for plugin configuration files
    • Added Java canonical bodies template specification, supporting canonical concepts including bool-cell, identity, and unit
  • Tests

    • Added automated verification tests to ensure consistency of plugin identifiers across Java canonical implementations

Review Change Stack

…eal CID

First implementation PR after #766 (body-template-memento spec) merged.
Authors three artifacts that close the §4 "MUST be content-addressed"
requirement honestly:

## 1. `mint-plugin-cid` binary

`implementations/rust/provekit-plugin-loader/src/bin/mint_plugin_cid.rs`

Reuses `compute_plugin_cid` (already in the plugin-loader crate, already
specced in `2026-05-12-plugin-protocol.md` §6.1) to mint the canonical
CID for any plugin file. Verified by running on the EXISTING slice 2
`java-canonical.json` and reproducing the pinned
`blake3-512:b7ad1160...` exactly. This is the missing recipe artifact:
the recipe was always in `compute_plugin_cid` (JCS over the whole
header sans `cid`, BLAKE3-512), but there was no entrypoint to call it
on a file. Now there is.

## 2. `java-canonical-bodies.json` with REAL minted CID

`menagerie/java-language-signature/specs/body-templates/java-canonical-bodies.json`

Three v1.0.0 body-template entries per `2026-05-13-body-template-memento.md` §2:
- `concept_name: "identity"`     → `return ${param0};`
- `concept_name: "bool-cell"`    → `return !${param0};`
- `concept_name: "unit"`         → `return;` (void)

Header carries real minted
`cid = blake3-512:a059900f182649c9bfbefdbc2a87931d185736cef1567cb71e625a29a7931a9dcc4c9b8cd07fa8ea8931056eae1586bc3610a37ce9be591ef5f4ec2d73de6a51`.

`provenance_cid` and envelope signature use the all-zeros sentinel
pattern (same as slice 2's `java-canonical.json`). Substrate-wide
sentinel convention for v0 defaults until real provenance signing
lands; tracked separately and not part of this PR.

## 3. Drift-prevention test

`implementations/rust/provekit-plugin-loader/tests/substrate_default_cids.rs`

For each substrate default plugin file, asserts that:
- The header's declared `cid` matches what `compute_plugin_cid` recomputes
  (catches anyone editing the file without re-minting).
- The declared `cid` matches the pinned value in this test (catches
  silent recipe-side drift).

Covers java-canonical.json (slice 2's sugar dict) AND the new
java-canonical-bodies.json. Adding a future default plugin file just
appends another `#[test]` here.

This guard is exactly what was missing on #765: there the JSON shipped
with the literal `PLACEHOLDER_TO_BE_MINTED_FROM_JCS_OF_CONTENT` string
where the CID should have been, and nothing failed CI.

## Tests

- `substrate_default_cids::java_canonical_sugar_cid_self_consistent`: PASS
- `substrate_default_cids::java_canonical_bodies_cid_self_consistent`: PASS
- Full `provekit-plugin-loader` regression: all green (17 + 9 + 2 +
  smaller groups, zero failures).

## Gated by

#766 (spec, merged at fe1f06b). This PR is the spec's first consumer.

## Blocks

#768 (cmd_transport Java early-return + is_stub flag threading) — needs
this PR's CID in the resource path it'll bake into the Java jar.
#769 (real body emission for identity / bool-cell / unit) — consumes
these body templates directly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 13, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 938dbb52-092c-49eb-b6ac-d5e65ae501ac

📥 Commits

Reviewing files that changed from the base of the PR and between fe1f06b and e9ef525.

📒 Files selected for processing (4)
  • implementations/rust/provekit-plugin-loader/Cargo.toml
  • implementations/rust/provekit-plugin-loader/src/bin/mint_plugin_cid.rs
  • implementations/rust/provekit-plugin-loader/tests/substrate_default_cids.rs
  • menagerie/java-language-signature/specs/body-templates/java-canonical-bodies.json

Walkthrough

This PR adds a CLI tool (mint-plugin-cid) that computes content identifiers for plugin JSON files, introduces a new Java canonical body-template specification, and implements CI drift-prevention tests that pin expected CIDs to detect unintended changes.

Changes

Plugin CID Computation and Validation

Layer / File(s) Summary
Java canonical bodies body-template specification
menagerie/java-language-signature/specs/body-templates/java-canonical-bodies.json
Defines a new JSON body-template named java-canonical-bodies with protocol version pep/1.7.0 and three canonical entries (bool-cell, identity, unit), each with Java verbatim templates and signature-parameter constraints.
Plugin CID computation CLI binary
implementations/rust/provekit-plugin-loader/Cargo.toml, implementations/rust/provekit-plugin-loader/src/bin/mint_plugin_cid.rs
Adds a new mint-plugin-cid executable that reads a plugin JSON file from CLI arguments, extracts the header object, computes its CID via compute_plugin_cid, and prints the result to stdout with appropriate error handling.
CID drift-prevention test suite
implementations/rust/provekit-plugin-loader/tests/substrate_default_cids.rs
Implements test infrastructure with helpers to locate plugin files, mint CIDs, read declared CID values, and assert declared-vs-minted equality against pinned test expectations. Two test cases validate Java canonical plugin files.

Possibly related PRs

  • TSavo/provekit#758: Introduces the compute_plugin_cid API and plugin header data structures that this PR's CLI tool and tests depend on.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A CLI that mints content IDs,
With test pinning to catch what hides,
Java templates take their place,
Drift detection at full pace,
Stable CIDs, verified with grace! 🎯

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main changes: adding a mint-plugin-cid binary and java-canonical-bodies.json file with computed CIDs.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/767-mint-plugin-cid

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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.

@TSavo TSavo merged commit c92103b into main May 13, 2026
5 of 6 checks passed
TSavo added a commit that referenced this pull request May 13, 2026
…ag threading (#768)

Third implementation PR in the body-template stack. Makes Java emission
flow through provekit-realize-java-core via JSON-RPC, and threads the
real-vs-stub kind back through cmd_bind so gaps.json emits per-concept
`bind-stub-body-emitted` entries per `body-template-memento.md` §5.

## What changes

### Java plugin: SugarRealizer + RpcServer (deliverable §1)

- `SugarRealizer.emitStub` now returns `Realization(source, isStub)`
  instead of a bare String. `isStub` is true when no body-template
  matched (stub fallback) and false when a template rendered a real body.
- `RpcServer.handleInvoke` now returns
  `{"source": "...", "is_stub": true|false}` instead of just `"..."`.
- `pom.xml` maven-resources-plugin copies the canonical
  `java-canonical-bodies.json` from menagerie/ into the jar at
  classpath `com/provekit/realize/`. Source of truth stays in menagerie;
  drift between jar and source is caught by the substrate_default_cids
  test from #767.

Empirical: jar built, RPC invoked, real body emits for `concept_name:
identity` (`return x;`), stub emits for `concept_name: result`
(`throw new UnsupportedOperationException(...)`), `is_stub` correct
in both responses.

### Rust: RealizedSource + cmd_transport plugin client (deliverable §2)

- `RealizedSource` gains `is_stub: bool` (§5 contract).
- `cmd_transport::realize_function` early-returns when
  `language == "java"` to `realize_via_java_plugin(...)`, which spawns
  `java -jar provekit-realize-java.jar --rpc`, sends a single
  `provekit.plugin.invoke` request, parses `{source, is_stub}` from the
  response. `is_stub` MUST be present — if missing or non-boolean, the
  plugin response is refused (no silent default).
- Discovery: `PROVEKIT_REALIZE_JAVA_JAR` env var if set, else
  CARGO_MANIFEST_DIR-relative default.
- All non-Java targets keep using the inline `stub_body_for` path
  (cmd_transport still owns those today). They set `is_stub: true`
  unconditionally because no body-template plugin exists for them in
  v1.0.0.

### Rust: cmd_bind per-concept gap emission (deliverable §3)

- `apply_canonical_rewrite` now returns `Vec<String>` of concept names
  whose realized body fell through to a stub. BTreeSet-deduplicated +
  sorted at return so output order is deterministic.
- Main cmd_bind flow augments `gaps` with one
  `bind-stub-body-emitted` entry per name BEFORE writing gaps.json.
- The unconditional hardcoded-count `bind-stub-body-emitted` gap in
  `run_bind_engine` is REMOVED — that was the lie #765 surfaced. The
  engine cannot know which concepts will fall through to stubs; only
  the realizer does. The engine now emits no F6 gap; per-concept gaps
  are emitted post-rewrite.

### Test: F6 → per-concept assertion

`f6_gaps_record_stub_body_emitted_per_concept` (renamed from
`f6_gaps_record_stub_body_emitted`) now exercises a cross-language
canonical rewrite (Rust → Go) where no body templates exist for Go,
so every concept must emit a per-concept gap. Asserts each entry's
`detail` names a specific concept via the literal substring `concept '`.

## Trinity verdict impact

```
trinity_round_trip: v0 loudly-bounded-lossy outcome (13 loss entries):
  [bind-stub-body-emitted] concept 'assert'
  [bind-stub-body-emitted] concept 'list'
  [bind-stub-body-emitted] concept 'option'
  [bind-stub-body-emitted] concept 'option-bind'
  [bind-stub-body-emitted] concept 'pair'
  [bind-stub-body-emitted] concept 'result'
  [bind-stub-body-emitted] concept 'result-bind'
  [bind-stub-body-emitted] concept 'retry-loop'
  [bind-stub-body-emitted] concept 'tagged-union'
  [leg-3-not-reached] ...
  [source-language-not-supported] (java)
  [v0-capability-gap] multi-lang lift_plugin dispatch deferred
  [v0-capability-gap] real ConceptAbstractionMemento catalog deferred
```

Verdict count went up (5 → 13) because we're being PRECISE now — each
entry names a specific concept/capability that closes a specific way.
`identity`, `bool-cell`, and `unit` are CORRECTLY ABSENT because real
bodies emit via the Java plugin. The 9 named stub concepts ARE the
exact #769 backlog.

## Tests

- `trinity_roundtrip_test`: PASS (13 honest entries vs old 5 mixed).
- `cmd_bind_integration::f6_gaps_record_stub_body_emitted_per_concept`: PASS.
- `cmd_bind_integration`: 27/27 PASS total.
- All other provekit-cli test groups GREEN (29 + 114 + 15 + 13 + 27 +
  1 + 2 + 19 + 4 = 224 PASS).
- Pre-existing `test_daemon_polyglot_smoke` failure (missing
  `provekit-linkerd` binary, documented prior session) unrelated.

## Gated by

#766 (spec), #767 (data + recipe). Both merged.

## Blocks

#769 (real body emission for the remaining 9 concepts). The 9
`bind-stub-body-emitted` entries this PR emits are #769's literal
deliverable list.

## Known follow-ups

- `TargetStyle::Java` match arms + `stub_body_for(Java, ...)` +
  `map_source_type` Java branch remain in cmd_transport.rs as dead code
  paths for non-bind realize callers (cross-language transport CLI).
  A separate boy-scout PR will remove them once those callers also
  delegate to the Java plugin. The production bind path NEVER hits
  them; the early-return guards.
- Slice 2 byte-identical tests are now plugin-vs-plugin tautologies
  (both sides ARE the plugin after this PR). They still pass; converting
  them to snapshot-vs-plugin or just deleting is follow-up.

Co-authored-by: Claude Code <agentwopr@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
TSavo added a commit that referenced this pull request May 13, 2026
…13→4 (#769)

Fills in real Java body templates for assert, list, option, option-bind,
pair, result, result-bind, retry-loop, tagged-union. Each non-canonical
template carries a literal ir-formula loss_record_contribution flagging
fixture-specific aspects (sentinel values, fixture-specific bind bodies,
tuple-to-array lifts, etc.) per Supra omnia rectum.

Trinity verdict drops from 13 loss entries to 4. All 9
bind-stub-body-emitted entries gone. The 4 remaining are substrate-
deferred capabilities (Rust-only source lift cascades through legs 2-3),
not template gaps — that's the next backlog after this stack.

Empirical: 0 stubs, 11 real return lines, 1 void-return (unit). swap_pair
emits 'return new long[] { b, a };'; classify emits the if-else cascade;
retry_until_success emits the real while-loop.

New CID minted via mint-plugin-cid (per #767 recipe):
blake3-512:e9c5dd41...204b

Pinned in substrate_default_cids drift test.

Also: SugarRealizer multi-line indent fix — each internal line of a
multi-line template now gets the same 8-space method-body indent.
Single-line bodies unaffected.

Closes the federation-by-construction boundary: Rust holds zero Java
syntax for the bind production path.

Co-authored-by: Claude Code <agentwopr@gmail.com>
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