Skip to content

v1.2.0 — Security, concurrency, and semantics fixes

Latest

Choose a tag to compare

@nficano nficano released this 25 May 16:12
· 23 commits to main since this release

What's fixed

This release closes 24 open issues across security, concurrency, runtime semantics, and docs. No new public API surface — but several behaviors changed from buggy → correct, which is why this is a minor bump rather than a patch.

Security

  • JWT challenge bindingJWTAuthValidator now requires a matching nonce claim when the runtime issues a challenge.
  • ModelUse subset escapesubsetViolation(of:) rewritten as a real glob-inclusion check so wildcard parents with suffix segments can't be escaped.
  • Lease validation — durations validated at grant/refresh; handleLeaseRefresh surfaces errors instead of swallowing them.

Concurrency

  • PendingRegistry + ARCPClient.ping use a slot state machine so waiters are registered before any timeout race.
  • Pending invocations are failed and progress/result streams finished when the transport closes; invoke's send-error path cleans up state.
  • ARCPRuntime.register race window closed (insert jobManagers before iterating registeredHandlers).
  • Subscriptions track owner session id; cleanup runs when the session ends. subscribe.event envelopes are skipped during route(), preventing recursive cascade on empty filters.
  • StreamManager.subscribeInbound refuses a second subscriber for the same stream id with failedPrecondition.

Client dispatch

  • Unmatched job.progress, job.result_chunk, and tool.error envelopes fall through to unhandled instead of being silently dropped or double-delivered.

Runtime semantics

  • Idempotency replay — terminal job.completed/failed/cancelled payloads persisted (scoped by principal + key) and replayed on duplicate invokes without re-running the handler.
  • Trace propagation — trace fields default to Tracing.current; JobManager propagates the inbound trace context across job lifecycle and handler emissions.
  • Artifact retention sweep starts in ARCPRuntime.init; lease expiry sweep starts in JobManager.init.
  • CredentialManager.rotate keeps every credential returned by the provisioner instead of silently discarding extras.
  • ULID generator preserves strict monotonicity across equal/backward clocks and overflow.
  • O(1) mailbox drain via head index with periodic compaction.

Compatibility

  • jwt-kit pinned under 5.3.0 to keep the package building on Swift 6.1.

Documentation

  • Resume guide / CONFORMANCE.md narrowed to same-session replay only.
  • Interrupt support documented as wire-acked only — no handler observation callback.
  • Heartbeat recovery documented as telemetry-only.
  • DocC comments added across the most user-facing public surface — now hosted on the Swift Package Index via the new .spi.yml.

Tests

  • New unit / integration suites covering Mailbox, LeaseManager, PendingRegistry, JWTAuth, client dispatch fallback, subscription cleanup, idempotency replay, and ULID burst.

Behavior changes to watch for

These are correctness fixes, but if you depend on the previous (buggy) behavior they may need code changes on your side:

  • JWT clients that did not echo the runtime's nonce claim back in their JWT will now fail auth.
  • Code that opened a second subscribeInbound for the same stream id will now error rather than silently override.
  • Handlers invoked with a duplicate IdempotencyKey no longer re-run — they replay the cached terminal payload.

Install

.package(url: "https://github.com/agentruntimecontrolprotocol/swift-sdk.git", from: "1.2.0"),

Full changelog: v1.1.0...v1.2.0