Skip to content

Releases: agentruntimecontrolprotocol/swift-sdk

v1.2.0 — Security, concurrency, and semantics fixes

25 May 16:12

Choose a tag to compare

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

v1.1.0 — Full ARCP v1.1 protocol conformance

22 May 04:04

Choose a tag to compare

What's new

Full ARCP v1.1 protocol surface

All normative v1.1 wire surfaces are now implemented:

  • job.result_chunk — multi-kind streamed results (text, event, log, thought, metric, binary) with back-pressure and cooperative close
  • Crash-and-resume — same IdempotencyKey → same job_id, buffered chunk replay via client.resultChunks(for:)
  • lease_constraints.expires_at — submission validation + in-handler expiry checks via context.checkLeaseExpiration()
  • cost.budget — per-invoke budget cap, context.charge() deductions, BUDGET_EXHAUSTED error, per-charge metrics
  • model.use — payload parsing, requested-model matching, runtime policy enforcement
  • provisioned_credentials — issue / rotate / revoke lifecycle with test provisioner

Documentation (docs/)

Complete docs/ tree added:

  • Architecture overview and RFC mapping guide
  • State diagrams for sessions, jobs, streams, subscriptions, and leases (SVG — light + dark)
  • Troubleshooting guide covering common integration errors
  • Extension authoring guide (§21 custom message types)

Recipes (Recipes/)

Four focused, self-contained runnable examples (each swift run from its directory):

Recipe Demonstrates
email-vendor-leases requestPermission + PermissionHandler veto (§15.4, §6.4)
mcp-skill Bridging MCP call_tool as an ARCP ToolHandler (§20, §15.4, §10, §18.3)
multi-agent-budget Cost-budget cap across serial worker steps (§17.3.1, §18.3)
stream-resume Crash-and-resume for streamed ResultChunkStream (§10, §19, §7.2)

Transports

  • StdioTransport — NDJSON framing over stdin/stdout (CLI arcp serve / arcp send / arcp tail / arcp replay)
  • WebSocketTransport — client-side WebSocket transport (server-side deferred to v1.2)

No breaking changes

v1.1.0 is fully backward-compatible with v1.0.x client code. All new surfaces are additive.

Deferred to v1.2

mTLS / OAuth2 auth, sidecar binary stream frames, scheduled jobs, multi-agent delegation, trust elevation, checkpoint-based resume, full WebSocket server. See CONFORMANCE.md.