feat(ts): port binaryCid + targetProofCid + sourceContractCid + EvidenceTerm to TypeScript kit#17
Conversation
Brings TypeScript kit to v1.4 cross-impl conformance with the Rust reference for three protocol fields surfaced in v1.3.0 / PR #10: binaryCid (.proof catalog, proof-file-format spec) Optional supply-chain back-pin to the compiled binary the bundle attests. Threaded through ProofEnvelopeInput, build, decode, and the catalog signing payload (so tampered pins break the catalog signature). Verifier accepts and surfaces the field; running-binary equality is documented as a follow-up. sourceContractCid + targetProofCid (BridgeDeclaration, ir-formal-grammar spec) Optional in this TS parser to remain backward-compatible with v1.1.0 peer-kit fixtures during migration. Spec lock order [kind, name, sourceSymbol, sourceLayer, sourceContractCid?, targetContractCid, targetProofCid?, targetLayer, notes?] enforced in strict mode in both parser and emitter. Surfaced in the kit authoring API (bridge() in property.ts) and the in-process primitiveBridge() registry. EvidenceTerm Already present in TypeScript (src/ir/formulas.ts + src/ir/grammar/parse.ts emitEvidence/parseEvidenceValue). Shape matches the Rust EvidenceTerm byte-for-byte under JCS. No port needed; conformance verified by inspection. Adds 7 new tests: parse.test.ts: bridge round-trip with new pins, strict-mode key order rejection, v1.1.0-shape backwards-compatibility. proofEnvelope/index.test.ts: binaryCid round-trip, signature inclusion (CID changes when pin set), determinism golden. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Warning Rate limit exceeded
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 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 (6)
✨ 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. Review rate limit: 0/1 reviews remaining, refill in 46 minutes and 24 seconds.Comment |
There was a problem hiding this comment.
Pull request overview
Ports additional protocol fields into the TypeScript kit to close a cross-implementation wire-format conformance gap (so TS can emit/parse/canonicalize the same JCS/CBOR bytes as Rust for equivalent logical inputs).
Changes:
- Adds optional
binaryCidsupport to.proofenvelope build/decode/verify signing payloads. - Extends BridgeDeclaration modeling + IR grammar parser/emitter to carry
sourceContractCidandtargetProofCidin spec-locked key order (strict mode enforced when present). - Adds/updates unit tests covering round-trip, strict key order, and determinism fingerprints.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| implementations/typescript/src/proofEnvelope/index.ts | Threads binaryCid through unsigned catalog body so it’s signed and survives decode/verify. |
| implementations/typescript/src/proofEnvelope/index.test.ts | Adds tests for binaryCid round-trip, signature verification, CID impact, and determinism. |
| implementations/typescript/src/ir/symbolic/property.ts | Extends BridgeDeclaration / BridgeSpec with optional sourceContractCid + targetProofCid. |
| implementations/typescript/src/ir/grammar/parse.ts | Adds new bridge optional keys; enforces strict key slot order; emits in spec-locked order. |
| implementations/typescript/src/ir/grammar/parse.test.ts | Adds strict-mode tests for v1.4 pins + backwards-compat behavior. |
| implementations/typescript/src/ir/extensions/bridges.ts | Extends primitive bridge records/inputs to carry the new bridge pin fields. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| * omit it. The verifier discharges | ||
| * `VerifyContractImplication(sourceContractCid, targetContractCid)` | ||
| * when both sides are present. |
| ? { targetProofCid: input.targetProofCid } | ||
| : {}), | ||
| targetLayer: input.targetLayer, | ||
| ...(input.notes ? { notes: input.notes } : {}), |
Closes a cross-impl conformance gap. The Rust reference implementation carries three protocol fields the TS kit was not modeling on the wire. This PR ports them to the TS kit at the parser/emitter/canonicalizer level so byte-for-byte JCS output can match Rust output for the same logical input.
Field-by-field
binaryCid(.proofcatalog)Spec:
protocol/specs/2026-04-30-proof-file-format.md(supply-chain anchor rule).implementations/typescript/src/proofEnvelope/index.ts: added optionalbinaryCidtoProofEnvelopeInputandDecodedProofCatalog; threaded through the unsigned body so it is part of the signed payload (tampering breaks the catalog signature); decoded back out; added back to the signing payload duringverifyProofEnvelopeso signatures continue to validate when the field is set.verifyProofEnvelopedoes not yet take arunningBinaryHashargument and checkhash(running) == binaryCid. That wiring is out of scope here and called out below.proofEnvelope/index.test.ts(emits deterministic bytes when binaryCid is set). It pins TS-vs-TS byte-equality and shape (blake3-512:[0-9a-f]{128}), and asserts that settingbinaryCidchanges the catalog CID (proof the field is in the signed payload, not silently dropped). Rust-side fixture withbinaryCidpopulated is a follow-up; the brief did not allow touchingimplementations/rust/.targetProofCid(BridgeDeclaration)Spec:
protocol/specs/2026-04-30-ir-formal-grammar.md(PR #10 promoted the attack-prevention example to normative).implementations/typescript/src/ir/symbolic/property.ts: added optionaltargetProofCidtoBridgeDeclarationandBridgeSpec; threaded throughbridge(...).implementations/typescript/src/ir/grammar/parse.ts: added toBRIDGE_DECL_OPTIONAL_KEYS; parser slots it aftertargetContractCidper the spec-locked order; strict-mode key-order check enforces the slot only when the field is present; emitter emits it in the locked position.implementations/typescript/src/ir/extensions/bridges.ts: boy-scout,PrimitiveBridgeInputandPrimitiveBridgeDeclarationalso expose the field so V8/ECMA-262-style kit authors can carry it through the in-process registry.src/verifier/bridgeEnforcement.ts->resolveBridgeTarget) currently resolves bridges bytargetContractCidonly. Pinning resolution to a specific.proofbundle CID, which is the whole point of the field per PR spec: promote targetProofCid attack-and-mitigation to normative example #10's normative attack-prevention example, is a verifier change beyond cross-impl wire conformance and is left as follow-up.sourceContractCid(BridgeDeclaration)Spec: same
2026-04-30-ir-formal-grammar.mdv1.4 grammar.targetProofCid, slotted betweensourceLayerandtargetContractCidper spec lock order.VerifyContractImplication(sourceContractCid, targetContractCid); that is verifier-pipeline work, not wire-conformance work.EvidenceTermIR variantimplementations/typescript/src/ir/formulas.ts(EvidenceTerm,EvidenceCertificate).implementations/typescript/src/ir/grammar/parse.ts(parseEvidenceValue,emitEvidence).ContractDeclaration.evidence?insrc/ir/symbolic/property.ts.src/ir/invariants.ts.{kind: "evidence", proofType, certificate: {tool, version, formulaHash, proofData}}matches the RustEvidenceTermandEvidenceCertificate(provekit-ir-types/src/lib.rs:9-15andprovekit-ir-symbolic/src/lib.rs:300-329) byte-for-byte under JCS. Rust serializer atprovekit-ir-symbolic/src/serialize.rs:29-48confirms the same key order. No port needed; conformance verified by reading both sides.Required-vs-optional choice for the bridge fields
Spec (
2026-04-30-ir-formal-grammar.mdlines 275-285) listssourceContractCidandtargetProofCidas required. Rustprovekit-ir-typeslib has them non-optional. The brief explicitly said "add the three optional fields" because every existing TS bridge fixture, peer-kit.prooffixture from C++/Go/Rust kit-out v1.1.0 directories, andbridges.test.tscase lacks them. Making them required in TS today would cascade-break peer-kit cross-lang tests that this PR is meant to keep green.The chosen scope cut: parse and emit them as optional in TS, document in the doc-comment + parser code that they are normatively required by the v1.4 grammar, and flag promotion to required as follow-up coordinated with peer-kit fixture migration.
Tests
7 new tests added; all 742 tests pass (was 735 before this PR).
implementations/typescript/src/ir/grammar/parse.test.ts:implementations/typescript/src/proofEnvelope/index.test.ts:binaryCidthrough build -> decode round-trip.verifyProofEnvelopepasses whenbinaryCidis set and untampered.binaryCidchanges the catalog CID (proof the field is in the signed payload).binaryCidset (golden fingerprint).Known follow-ups (called out for reviewers, not part of this PR)
binaryCidenforcement: wireverifyProofEnvelopeto take a running-binary hash and reject on mismatch per spec section 5 rule 7.targetProofCidenforcement: changeresolveBridgeTargetin the bridge enforcement pipeline to pin by.proofbundle CID when the field is set, per PR spec: promote targetProofCid attack-and-mitigation to normative example #10's normative attack example.sourceContractCidenforcement: dischargeVerifyContractImplication(sourceContractCid, targetContractCid)during bridge enforcement.proofEnvelope/index.test.tsis TS-vs-TS only. Rust-side fixture withbinaryCidpopulated needs to be minted and pinned to the same hex; could not be done in this PR per the no-touch-Rust constraint.Pre-existing CI surface (not introduced here)
pnpm exec tsc --noEmitreports pre-existing errors insrc/ir/invariants.tsandsrc/ir/invariants.test.tsthat reference symbols (Num,StrConst,Var,property) not exported by the modules they import from. These are unrelated to this PR; CI runspnpm test(vitest), nottsc --noEmit, and all 742 vitest tests pass.Test plan
pnpm testpasses (742 passed, 2 skipped, 4 todo)parse.test.tsandproofEnvelope/index.test.tscases all green.prooffixture withbinaryCidset and assert TS bytes equal Rust bytes for the same logical inputCo-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com