Skip to content

feat: discovery profile spec + 3-step algorithm#421

Merged
jithinraj merged 5 commits intofeat/mappings-a2afrom
feat/discovery-profile
Feb 23, 2026
Merged

feat: discovery profile spec + 3-step algorithm#421
jithinraj merged 5 commits intofeat/mappings-a2afrom
feat/discovery-profile

Conversation

@jithinraj
Copy link
Member

Summary

  • New Discovery Profile spec: 3-step discovery algorithm (Agent Card, well-known, header probe)
  • discoverPeacCapabilities() function implementing the algorithm with SSRF hardening
  • PeacDiscoveryResult type with source attribution

Changes

New files

  • docs/specs/DISCOVERY-PROFILE.md: Normative spec for PEAC discovery

Modified files

  • packages/mappings/a2a/src/discovery.ts: added discoverPeacCapabilities, discoverPeacWellKnown, discoverPeacViaHeaderProbe
  • packages/mappings/a2a/src/index.ts: re-exports new types and function
  • packages/mappings/a2a/tests/discovery.test.ts: 8 new tests (24 total)

Design decisions

  • DD-110: 3-step discovery algorithm
  • Polish C: SSRF protections applied to all network-facing discovery

Test plan

  • 8 new discovery tests pass
  • All 70 A2A tests pass
  • Full gate: build (78/78), lint, typecheck, test (178 files / 4316 tests)
  • guard.sh, check-planning-leak.sh pass

Stacked on

Discovery Profile (docs/specs/DISCOVERY-PROFILE.md):
- 3-step discovery algorithm: Agent Card -> well-known -> header probe
- SSRF protection requirements per Polish C
- PeacDiscoveryResult type with source attribution
- Caching recommendations and security considerations

Discovery code (@peac/mappings-a2a):
- discoverPeacCapabilities(): implements 3-step algorithm
- discoverPeacWellKnown(): /.well-known/peac.json discovery
- discoverPeacViaHeaderProbe(): HEAD request with PEAC-Receipt check
- PeacDiscoveryResult, PeacDiscoverySource types
- 8 new tests (24 total discovery tests)
Enforce the canonical 3-step JWKS resolution algorithm:
iss -> peac-issuer.json -> jwks_uri -> JWKS

- Add shared jwks-resolver.ts: single cache, strict discovery, 6 new
  kernel error codes (E_VERIFY_ISSUER_CONFIG_MISSING, _INVALID,
  _MISMATCH, JWKS_URI_INVALID, INSECURE_SCHEME_BLOCKED, JWKS_INVALID)
- Rewrite verify.ts to delegate to jwks-resolver (remove legacy
  fallback paths, local JWK/JWKS types, parallel cache)
- Rewrite verifier-core.ts to delegate to jwks-resolver (remove
  private fetchIssuerConfig, private cache, direct SSRF fetch)
- Add discovery surface drift guard to guard.sh (scoped to
  packages/protocol/src/*.ts production code)
- Update PEAC-ISSUER.md: strict key discovery section, new error table
- Update PEAC-TXT.md: peac.txt MUST NOT be used for key discovery
- Update docs/receipts.md and docs/ARCHITECTURE.md references
- Add 19 tests covering all error codes, caching, and no-fallback
Discovery (P0-2, P0-3, P1-A, P1-C):
- Add resolveHostname option for portable DNS rebinding defense
- Replace blanket proxy bypass claim with accurate proxy policy
- Add userinfo rejection (user:pass@host URLs blocked)
- Add RFC 8174 reference alongside RFC 2119 in normative keywords
- Spec sections 4.1, 4.7, 4.8 updated to match implementation
- 4 new tests: userinfo rejection, DNS rebinding (2), public IP pass

AGENTS.md (P1-B):
- Update A2A Agent Card example to v0.3.0 capabilities.extensions[]
- Fix discovery path to /.well-known/agent-card.json (v0.3.0 canonical)
- Update JWKS path to /.well-known/peac-issuer.json
Post-commit formatter corrections for JWKS resolver changes:
- PEAC-ISSUER.md: canonicalize issuer to origin, stricter jwks_uri validation
- guard.sh: updated discovery surface drift patterns
- Protocol test and implementation alignment
@jithinraj jithinraj changed the title feat: discovery profile spec and 3-step algorithm (DD-110) feat: discovery profile spec + 3-step algorithm Feb 23, 2026
@jithinraj jithinraj merged commit a46005b into feat/mappings-a2a Feb 23, 2026
1 check passed
@jithinraj jithinraj deleted the feat/discovery-profile branch February 23, 2026 18:29
jithinraj added a commit that referenced this pull request Feb 23, 2026
* feat: evidence carrier types, schemas, and conformance fixtures (DD-124)

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

* feat: @peac/mappings-a2a package for A2A evidence carrier (DD-126, DD-128)

New mapping package for Agent-to-Agent Protocol (A2A) v0.3.0 integration.
Maps PEAC evidence carriers to A2A metadata using the PEAC extension URI
as the metadata key with nested carrier payload.

- types: minimal A2A types from spec v0.3.0 (no @a2a-js/sdk dependency)
- attach: attachReceiptToMetadata/TaskStatus/Message/Artifact
- extract: sync (structural, DD-131) + async (receipt_ref consistency, DD-129)
- carrier: A2ACarrierAdapter implementing CarrierAdapter interface
- header: parseA2AExtensionsHeader/buildA2AExtensionsHeader (DD-86)
- discovery: discoverAgentCard with SSRF hardening (scheme allowlist,
  private IP rejection, 256KB cap, content-type check, redirect rejection)
- 62 tests across 5 test files

* chore: update pnpm-lock.yaml for @peac/mappings-a2a

* feat: discovery profile spec + 3-step algorithm (#421)

* feat: discovery profile spec and 3-step algorithm (DD-110)

Discovery Profile (docs/specs/DISCOVERY-PROFILE.md):
- 3-step discovery algorithm: Agent Card -> well-known -> header probe
- SSRF protection requirements per Polish C
- PeacDiscoveryResult type with source attribution
- Caching recommendations and security considerations

Discovery code (@peac/mappings-a2a):
- discoverPeacCapabilities(): implements 3-step algorithm
- discoverPeacWellKnown(): /.well-known/peac.json discovery
- discoverPeacViaHeaderProbe(): HEAD request with PEAC-Receipt check
- PeacDiscoveryResult, PeacDiscoverySource types
- 8 new tests (24 total discovery tests)

* feat: strict discovery surface contract with shared JWKS resolver

Enforce the canonical 3-step JWKS resolution algorithm:
iss -> peac-issuer.json -> jwks_uri -> JWKS

- Add shared jwks-resolver.ts: single cache, strict discovery, 6 new
  kernel error codes (E_VERIFY_ISSUER_CONFIG_MISSING, _INVALID,
  _MISMATCH, JWKS_URI_INVALID, INSECURE_SCHEME_BLOCKED, JWKS_INVALID)
- Rewrite verify.ts to delegate to jwks-resolver (remove legacy
  fallback paths, local JWK/JWKS types, parallel cache)
- Rewrite verifier-core.ts to delegate to jwks-resolver (remove
  private fetchIssuerConfig, private cache, direct SSRF fetch)
- Add discovery surface drift guard to guard.sh (scoped to
  packages/protocol/src/*.ts production code)
- Update PEAC-ISSUER.md: strict key discovery section, new error table
- Update PEAC-TXT.md: peac.txt MUST NOT be used for key discovery
- Update docs/receipts.md and docs/ARCHITECTURE.md references
- Add 19 tests covering all error codes, caching, and no-fallback

* fix: discovery SSRF hardening and AGENTS.md A2A v0.3.0 alignment

Discovery (P0-2, P0-3, P1-A, P1-C):
- Add resolveHostname option for portable DNS rebinding defense
- Replace blanket proxy bypass claim with accurate proxy policy
- Add userinfo rejection (user:pass@host URLs blocked)
- Add RFC 8174 reference alongside RFC 2119 in normative keywords
- Spec sections 4.1, 4.7, 4.8 updated to match implementation
- 4 new tests: userinfo rejection, DNS rebinding (2), public IP pass

AGENTS.md (P1-B):
- Update A2A Agent Card example to v0.3.0 capabilities.extensions[]
- Fix discovery path to /.well-known/agent-card.json (v0.3.0 canonical)
- Update JWKS path to /.well-known/peac-issuer.json

* fix: JWKS resolver spec alignment and formatter corrections

Post-commit formatter corrections for JWKS resolver changes:
- PEAC-ISSUER.md: canonicalize issuer to origin, stricter jwks_uri validation
- guard.sh: updated discovery surface drift patterns
- Protocol test and implementation alignment

* fix: JWKS resolver improvements (issuer normalization, error taxonomy, LRU cache, drift gate)

* fix: Discovery Profile and PEAC-ISSUER spec corrections

DISCOVERY-PROFILE.md:
- Add RFC 8174 reference alongside RFC 2119 (P1-A)
- Rewrite section 4.1: portable two-level DNS rebinding defense
  with optional resolveHostname callback (P0-3)
- Rewrite section 4.7: accurate proxy policy covering Node.js
  --use-env-proxy and http.setGlobalProxyFromEnv() (P0-2)
- Add section 4.8: userinfo rejection requirement (P1-C)
- Add conformance items 6 (userinfo) and 7 (DNS resolution)

PEAC-ISSUER.md:
- Tighten verifier conformance: explicit MUST NOT assume JWKS
  location without resolving issuer config (section 13.2)

* chore: format AGENTS.md and discovery.ts

* docs: add Trojan Source protection note to SECURITY.md

Clarifies that GitHub's bidi Unicode warning banner is heuristic;
the repo runs a fail-closed Trojan Source scan on every CI run and
local guard.sh invocation as the authoritative check.

* fix: protocol-level spec polish across all normative documents

PEAC-ISSUER.md:
- Add RFC 8174 to keyword clause and references section
- Add RFC 2119 to references section (was cited but not listed)
- Add language tags to fenced code blocks (pseudocode -> text)

PEAC-TXT.md:
- Add RFC 8174 to keyword clause and references section
- Add cross-reference to PEAC-ISSUER.md in references
- Add section 9.4 error codes table (9 error codes with HTTP mappings)
- Add language tags to fenced code blocks

AGENTS.md:
- Fix Key Directory to reference normative discovery chain
  (peac-issuer.json -> jwks_uri) instead of direct JWKS URL
- Add ES256 alongside EdDSA in supported algorithms
- Add Specification column with cross-references to spec docs

.github/SECURITY.md:
- Add 0.11.x to supported versions table
- Update algorithms: EdDSA (recommended) + ES256
- Update key rotation description to match JWKS kid model

* chore: bump registries to 0.10.0 and refresh extended README

- Bump specs/kernel/registries.json from 0.9.19 to 0.10.0
- Add stripe to payment_rails, a2a and ucp to agent_protocols
- Update docs/README_LONG.md: ten pillars, A2A mapping status,
  ES256 algorithm support, mcp-server/middleware/capture-node
  packages, layer map with L3.5/L5/L6, pnpm >= 9

* fix: address pre-merge audit findings across discovery, JWKS, and publish infra

- Discovery Profile: rename jwks_uri to issuer_config_url to prevent
  a second key-discovery path that bypasses the normative issuer chain
  (peac-issuer.json -> jwks_uri -> JWKS)
- JWKS resolver: return E_VERIFY_ISSUER_CONFIG_INVALID (not
  E_VERIFY_INSECURE_SCHEME_BLOCKED) for malformed/non-hierarchical
  issuer URLs
- Publish infra: add @peac/mappings-a2a to check-publish-list.sh
  expected packages and publish-manifest.json pendingTrustedPublishing
- Fix package count consistency in check-publish-list.sh (17 untested)

* fix: add RFC 8174 alongside RFC 2119 in 6 normative spec documents

Per BCP 14, specs citing RFC 2119 keywords should also cite RFC 8174
to clarify that keywords are normative only when capitalized. Updated:
AGENT-IDENTITY, ATTRIBUTION, DISPUTE, INTERACTION-EVIDENCE,
PROTOCOL-BEHAVIOR, SCHEMA-NORMALIZATION.

* chore: regenerate error codes from errors.json

New error codes added in this branch (JWKS resolver, issuer config,
insecure scheme) were missing from the generated TypeScript file.

* fix: remove unused imports in mappings-a2a

* style: format extract.ts after import cleanup

* fix: align discovery fixture version with schema_version
jithinraj added a commit that referenced this pull request Feb 23, 2026
Evidence Carrier Contract + A2A Mapping release.

- Bump all 65 workspace packages to 0.11.1
- CHANGELOG entry for Evidence Carrier Contract, A2A mapping,
  MCP _meta carrier, ACP/UCP/x402 carrier adoption, discovery profile
- AGENTS.md: v0.11.1 carrier format, A2A metadata example
- Normative specs: EVIDENCE-CARRIER-CONTRACT.md, A2A-RECEIPT-PROFILE.md,
  MCP-EVIDENCE-PROFILE.md
- Registry: a2a, ucp, stripe entries (version 0.10.0)

PRs: #414-#421 (8 merged)
Design decisions: DD-124 through DD-131
jithinraj added a commit that referenced this pull request Feb 23, 2026
Evidence Carrier Contract + A2A Mapping release.

- Bump all 65 workspace packages to 0.11.1
- CHANGELOG entry for Evidence Carrier Contract, A2A mapping,
  MCP _meta carrier, ACP/UCP/x402 carrier adoption, discovery profile
- AGENTS.md: v0.11.1 carrier format, A2A metadata example
- Normative specs: EVIDENCE-CARRIER-CONTRACT.md, A2A-RECEIPT-PROFILE.md,
  MCP-EVIDENCE-PROFILE.md
- Registry: a2a, ucp, stripe entries (version 0.10.0)
- Spec fixes: embed-only HTTP in v0.11.1, MCP dual-legacy wording,
  softened RFC 9711 analogy, DD-129 producer/consumer split,
  Node >= 20 runtime vs >= 22 dev baseline, fixture description clarity,
  removed duplicate UCP registry entry

PRs: #414-#421 (8 merged)
Design decisions: DD-124 through DD-131
jithinraj added a commit that referenced this pull request Feb 23, 2026
Evidence Carrier Contract + A2A Mapping release.

- Bump all 65 workspace packages to 0.11.1
- CHANGELOG entry for Evidence Carrier Contract, A2A mapping,
  MCP _meta carrier, ACP/UCP/x402 carrier adoption, discovery profile
- AGENTS.md: v0.11.1 carrier format, A2A metadata example
- Normative specs: EVIDENCE-CARRIER-CONTRACT.md, A2A-RECEIPT-PROFILE.md,
  MCP-EVIDENCE-PROFILE.md
- Registry: a2a, ucp, stripe entries (version 0.10.0)
- Spec fixes: embed-only HTTP in v0.11.1, MCP dual-legacy wording,
  softened RFC 9711 analogy, DD-129 producer/consumer split,
  Node >= 20 runtime vs >= 22 dev baseline, fixture description clarity,
  removed duplicate UCP registry entry

PRs: #414-#421 (8 merged)
Design decisions: DD-124 through DD-131
jithinraj added a commit that referenced this pull request Feb 23, 2026
* test(smoke): MCP carrier e2e round-trip

Full flow: issue -> computeReceiptRef -> attachReceiptToMeta ->
extractReceiptFromMetaAsync -> verifyLocal. No network calls, no clock
dependencies; uses deterministic key material for reproducible failures.

Tests:
- Full round-trip with offline verification
- Tampered receipt_ref detection (DD-129)
- Legacy org.peacprotocol/receipt extraction with receipt_ref computation
- Round-trip carrier field preservation
- Null return for missing _meta

Also re-enables tests/smoke in vitest config and adds @peac/mappings-mcp
alias for root-level test resolution.

* chore(release): v0.11.1

Evidence Carrier Contract + A2A Mapping release.

- Bump all 65 workspace packages to 0.11.1
- CHANGELOG entry for Evidence Carrier Contract, A2A mapping,
  MCP _meta carrier, ACP/UCP/x402 carrier adoption, discovery profile
- AGENTS.md: v0.11.1 carrier format, A2A metadata example
- Normative specs: EVIDENCE-CARRIER-CONTRACT.md, A2A-RECEIPT-PROFILE.md,
  MCP-EVIDENCE-PROFILE.md
- Registry: a2a, ucp, stripe entries (version 0.10.0)
- Spec fixes: embed-only HTTP in v0.11.1, MCP dual-legacy wording,
  softened RFC 9711 analogy, DD-129 producer/consumer split,
  Node >= 20 runtime vs >= 22 dev baseline, fixture description clarity,
  removed duplicate UCP registry entry

PRs: #414-#421 (8 merged)
Design decisions: DD-124 through DD-131
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.

1 participant