feat: MCP carrier with _meta format and reserved key guard#417
Merged
feat: MCP carrier with _meta format and reserved key guard#417
Conversation
Ship PeacEvidenceCarrier types (Layer 0, zero runtime) and Zod schemas with shared computeReceiptRef() helper (Layer 1). Includes carrier conformance fixtures (5 valid, 3 invalid) and verifyReceiptRefConsistency() for DD-129 async extraction enforcement. - kernel: PeacEvidenceCarrier, CarrierAdapter<T,U>, CarrierMeta types - kernel: PEAC_RECEIPT_HEADER canonical constant (DD-127) - schema: ReceiptRefSchema, CompactJwsSchema, PeacEvidenceCarrierSchema - schema: computeReceiptRef() with WebCrypto runtime guard - schema: validateCarrierConstraints() transport-aware validation - schema: verifyReceiptRefConsistency() for tamper detection - schema: CARRIER_TRANSPORT_LIMITS per-transport size constants - conformance: 8 carrier fixtures in specs/conformance/fixtures/carrier/ - conformance: carrier category registered in manifest and tracking
…DD-125) Add Evidence Carrier Contract support to @peac/mappings-mcp. New _meta carrier format uses receipt_ref + receipt_jws keys under org.peacprotocol/ prefix. Legacy peac_receipt and org.peacprotocol/receipt keys remain readable for backward compatibility (DD-125 phase 1). - meta: attachReceiptToMeta/extractReceiptFromMeta (sync + async) - meta: McpCarrierAdapter implementing CarrierAdapter interface - meta: legacy org.peacprotocol/receipt auto-computes receipt_ref (Polish B) - guard: assertNotMcpReservedKey checks second label per MCP 2025-11-25 spec - legacy: extractReceipt() reads _meta keys, legacy _meta key, and peac_receipt - 31 new tests (20 meta + 11 guard), all existing tests unchanged
The MCP spec reserves prefixes where "mcp" or "modelcontextprotocol" appears as a non-last label (followed by another label). The previous implementation incorrectly checked only the second label (index 1). Now checks all labels except the last, matching the spec exactly. Reserved: mcp.dev/x, tools.mcp.com/x, api.modelcontextprotocol.org/x Not reserved: dev.mcp/x, io.modelcontextprotocol/x, com.example.mcp/x
The MCP spec states: "Any prefix where the second label is `modelcontextprotocol` or `mcp` is reserved." Previous implementation used a non-last-label rule which incorrectly treated `mcp.dev/...` as reserved and `dev.mcp/...` as not reserved. Now correctly checks only labels[1] (0-indexed): Reserved: dev.mcp/..., io.modelcontextprotocol/..., com.mcp.tools/... Not reserved: mcp.dev/..., modelcontextprotocol.io/..., com.example.mcp/...
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
@peac/mappings-mcp_metacarrier format:org.peacprotocol/receipt_ref+org.peacprotocol/receipt_jwsassertNotMcpReservedKey()checks second label per MCP 2025-11-25 specpeac_receiptandorg.peacprotocol/receiptkeys remain readable (DD-125 phase 1)Key Design
DD-125: 3-Phase Legacy Deprecation
extractReceipt()reads BOTH legacy and_meta.attachReceiptToMeta()defaults to_meta;opts.legacyFormat: truefor legacy.MCP Reserved Key Guard (Correction Item 3)
Per MCP spec 2025-11-25, the reserved rule checks the second label (dot-separated):
dev.mcp/anything-> RESERVED (2nd label =mcp)io.modelcontextprotocol/x-> RESERVED (2nd label =modelcontextprotocol)com.example.mcp/data-> NOT reserved (2nd label =example)org.peacprotocol/receipt_ref-> NOT reserved (2nd label =peacprotocol)Polish B: Legacy _meta Key Backward Compat
extractReceiptFromMetaAsync()readsorg.peacprotocol/receipt(v0.10.13 format), computesreceipt_reffrom the JWS, and returns a properPeacEvidenceCarrier.Test plan
pnpm build(77/77),pnpm test(4280), lint, typecheck, guards passStacked on: PR #414 (
feat/evidence-carrier-types)