Skip to content

Ironflow v0.32.0

Ironflow v0.32.0 closes the SDK exposure audit opened in #1892. Go, Node, and Browser gain the complete function-lifecycle and read surface, EnvironmentService becomes a real mounted ConnectRPC service, and the Browser SDK sheds three administrative surfaces that never belonged in a browser bundle. Tier-1 pub/sub resume cursors reach all four SDKs, and a reconnect now restores the subscription it started with instead of quietly degrading to plain fan-out.

  • Browser SDK: projection rebuild is no longer exposed in @ironflow/browser. The Browser SDK is a data-plane client for projection reads, subscriptions, event emission, and topic publishing; rebuild, pause, resume, cancel, delete, partition inventory, and SQL-projection creation are operator actions. Migration: move ironflow.rebuildProjection(...) to @ironflow/node as client.projections.rebuild(...), the Go SDK, the generated Python client, the CLI, the dashboard, or another trusted backend (#1892, #1906)
  • Browser SDK: config mutations and user administration are no longer exposed in @ironflow/browser. Removed configManager().set(), .patch(), and .delete(), the ironflow.users namespace, and the Browser package re-exports of ConfigSetResult, User, CreateUserInput, and UpdateUserInput. These called routes classified server-only — server RBAC prevented an authorization bypass, but shipping admin helpers in a browser package encouraged applications to embed administrative credentials. Config get, list, and watch remain. Migration: move config mutations and user CRUD to @ironflow/node, the Go SDK, the generated Python client, the CLI, the dashboard, or a trusted backend endpoint; browser code consumes the result through configManager().get(), .list(), or .watch() (#1892, #1906)
  • Python SDK: the generated step-patch method is now steps_patch(). The route was grouped under runs, which produced the unrelated name runs_create(). Migration: replace client.runs_create(body=...) with client.steps_patch(body=...). Generated REST methods now also expose every header declared by the route manifest as a keyword argument, including if_match, if_none_match, idempotency_key, and x_ironflow_environment; BaseClient.request() remains available for undeclared headers (#1892, #1906)
  • TypeScript: replay applies only to the initial subscribe frame, not to every reconnect. A transient disconnect no longer replays the same historical window again. Migration: applications that depended on replay running after each reconnect must use startAfterSequence for positioned fan-out delivery, or a consumer group for durable load-balanced delivery. An unpositioned fan-out subscription reconnects from the current tail and can miss events published while it was offline (#1890, #1895)
  • Tier-1 resume cursors reach the Go, Node, and Browser SDKs. v0.31.0 shipped the server and protocol side of start_after_sequence; this release exposes it through the client libraries and finishes the reconnect semantics behind it. A cursor is now reconnect opt-in even when auto-reconnect is disabled, reconnects resume from the last delivered sequence with exact uint64 cursors preserved, and pre-ACK disconnects, repeated failed redials, cancellation races, late ACKs, and same-pattern replacement are all handled without ghost subscriptions. WebSocket subscriptions that combine a cursor with a consumer group are rejected, matching ConnectRPC. Delivery stays at-least-once, so handlers must tolerate an in-flight event arriving twice. The accepted contract is recorded in ADR 0064 (#1890, #1895, #1897)
  • Tier-1 subscription reconnects restore the original subscription identity. Go WebSocket reconnects retain Filter, ConsumerGroup, IncludeMetadata, AckMode, Backpressure, and Namespace instead of silently reverting to a plain fan-out subscription; Node and Browser transports retain the same fields. Migration: Go applications that added a downstream filter or broadcast deduplication to compensate for lost reconnect options can remove that workaround (#1890, #1895)
  • Curated SDK clients now cover the complete high-value read and function lifecycle surface. Go, Node, and Browser gain function get/status/delete/history/version/rollback, TriggerBatch, event list/get/name-facet reads, run step and touched-stream introspection, and shared public result types. Go and Node also gain projection partition listing; Browser keeps that tenant-wide operator query outside its public boundary. Every method has request-shape and response tests (#1892, #1906)
  • EnvironmentService is a real, mounted ConnectRPC surface. All five declared RPCs are served and registered in the route manifest. CRUD uses the current project and tenant scope without returning credential material. Legacy environment-key rotation now maps onto first-class API-key records: it preserves roles, expiry, and tool scopes, rotates the sole environment key or the caller’s own key, and rejects ambiguous multi-key admin requests instead of revoking an arbitrary credential. Go and JavaScript environment methods stay REST-backed; Python gains typed rpc.environments.get() and .rotate_api_key() (#1892, #1906)
  • Node KV watch and consumer-group management reach parity. @ironflow/node exposes bucket.watch() over the credential-safe WebSocket subprotocol, plus client.consumerGroups.{create,get,list,update,delete} with typed partial updates. The Go SDK gains its missing UpdateConsumerGroup, including field-mask generation that preserves explicit zero values (#1892, #1906)
  • Browser clients can publish directly to developer pub/sub topics. @ironflow/browser exposes publish(topic, data, options) over PubSubService/Publish, including idempotency keys and numeric JetStream sequence results. Topic inventory and consumer-group administration remain trusted-client concerns (#1892, #1906)
  • Browser WebSocket credentials no longer appear in URL query strings. @ironflow/browser carries WebSocket bearer credentials as base64url-encoded subprotocol metadata for subscriptions and KV watch. The server authenticates that metadata while negotiating only the stable ironflow.v1 protocol, so it never reflects the credential-bearing value. Legacy ?token= authentication stays accepted server-side for older clients. Development browser contexts now warn when configured with a long-lived ifkey_ environment key — use a short-lived session token from a trusted backend instead (#1892, #1906)
  • Consumer-group and durable publish edge cases are safe and complete. Node and Go reject empty consumer-group updates instead of sending an empty field mask that the server reads as a full replacement, and both clients follow consumer-group pagination until every page is returned. Node durable step.publish() now forwards its advertised idempotency key (#1892, #1906)
  • A generated SDK parity matrix is published. docs/reference/sdk-parity-matrix.md covers 133 capabilities across REST, ConnectRPC, other transports, four SDKs, langgraph, tests, and docs, rendered from a tracked CSV with file:line evidence. A --check mode is wired into make check-sdk-comparison, so the page cannot drift from its source (#1892, #1893)
  • Extended administration has an explicit generated-client boundary. Policy dry-run, policy versions and rollback, policy templates, API-key role replacement, and authentication audit stay available through generated Python REST or RPC methods, the dashboard, the CLI where available, and raw authenticated endpoints. They intentionally do not receive curated Go, Node, or Browser wrappers, and the comparison annotations now distinguish that decision from an unimplemented gap. Environment administration ConnectRPC routes are classified server-only in the generated manifest to match (#1892, #1906)
  • Documentation synced against the implementation across the CLI reference, SDK reference, deployment guides, and the bundled agent skills (#1908)
  • Bundled agent skills trimmed. The ironflow-ops skill no longer ships scripts/inspect-run.sh; use ironflow inspect <run_id> directly (#1903)

Ironflow Desktop ships on its own cadence — see the Desktop changelog for its release notes.