Skip to content

Releases: valeriouberti/apology-protocol

Release list

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 17 Aug 14:12
368cd67

Canonical-bytes idempotency keys, aligned with A2A §8.4.1 (Agent Card
signing) — design settled in
a2aproject/A2A#2124.

Added

  • deriveIdempotencyKey(plan, stepId) — keys of the form
    ${sagaId}:${stepId}:${hex(sha256(canonical_step_bytes))}: prefix for
    debuggability, hash suffix for integrity. Byte pipeline: exclude the
    field carrying the integrity value (plan-level signature, the step's
    own idempotencyKey) → presence rule → JCS (RFC 8785) → SHA-256.
  • key-integrity check — a plan carrying canonical-bytes keys has
    them recomputed; same key with different bytes fails validation ("a
    replay presented a different payload under the same idempotency key").
    Legacy ${sagaId}:${stepId} keys claim no integrity and are left alone.
  • Vendored JCS (RFC 8785) in src/canonical/jcs.ts, verified against
    the official test vectors (vendored in test/fixtures/jcs/). Zod
    remains the only runtime dependency.
  • The presence rule, explicit and testable
    (src/canonical/presence.ts): omitted optional fields stay omitted;
    explicitly-set fields are included even at their documented default —
    defaults are validator semantics, not bytes. Pinned by the fixture pair
    presence-divergence-omitted.json /
    presence-divergence-explicit-default.json, which MUST hash
    differently.
  • Fixture key-mismatch-replay.json: same key, different bytes, refused
    before execution.
  • Exports: deriveIdempotencyKey, hashStep, canonicalize,
    preparePlanForHashing, prepareStepForHashing, keyIntegrity.

Changed

  • The schema now accepts both key forms: legacy ${sagaId}:${stepId} and
    canonical-bytes ${sagaId}:${stepId}:${sha256hex}. Existing plans keep
    validating unchanged.