Releases: CaliLuke/loom
Release list
v1.7.1
Highlights
- Updates Loom's maintained Go dependencies, including gRPC 1.82.1, libopenapi 0.38.7, Kong 1.16.0, smithy-go 1.27.4, and logr 1.4.4.
- Updates the GitHub Actions Go and Node setup steps to v7 and keeps the checked-in HTTP and JSON-RPC fixture modules synchronized with the framework dependency graph.
- Removes the unused pkg/errors dependency and refreshes Loom's README positioning and Loom-MCP skill guidance.
Upgrade notes
This is a maintenance release with no intended API or generated-code contract changes. Downstream projects can update to v1.7.1 without regeneration solely for this release.
Full Changelog: v1.7.0...v1.7.1
v1.7.0
Highlights
- Strengthens Loom's generator and transport lifecycle reliability across HTTP, JSON-RPC, SSE, WebSocket, and gRPC surfaces.
- Improves typed JSON-RPC generation and transport observability so generated applications preserve request lifecycle behavior consistently.
- Adds transactional plugin-output handling and completes framework reliability and modularity cleanup.
- Makes the release workflow resilient to isolated-worktree lint caches and source-selection test environments.
Upgrade notes
Regenerate generated clients and servers with loom gen after upgrading to receive the transport and code-generation updates. Projects that pin Loom, including loom-mcp, should update to v1.7.0 and run their normal generation and integration verification.
Full Changelog: v1.6.2...v1.7.0
v1.6.2
Highlights
- Fixes the shared SSE response writer so a successful HTTP response is committed exactly once for the full stream lifecycle.
- Eliminates
http: superfluous response.WriteHeader calllogs when HTTP or JSON-RPC/MCP streams send multiple events or heartbeat comments. - Preserves lazy first-frame initialization, idempotent
Open, per-frame flushing, write deadlines, cancellation, failure observability, and closed-stream behavior.
Upgrade notes
This is a backward-compatible runtime fix for users of Loom v1.6.0 and v1.6.1. Upgrade to v1.6.2 to pick up the corrected shared SSE writer. No generated output changed, so regeneration is not required for this fix alone; projects that pin Loom should update the dependency and follow their normal generation workflow.
Full Changelog: v1.6.1...v1.6.2
v1.6.1
Highlights
- Stabilizes the bounded WebSocket write regression test by creating deterministic socket backpressure.
- Removes race-runner and machine-speed sensitivity from the release gate without changing WebSocket runtime behavior.
Upgrade notes
- This is a test/release-quality patch over v1.6.0; no generated API or runtime behavior changes are required.
- Projects already using v1.6.0 can upgrade directly without regeneration solely for this patch.
Verification
make release-preflight- Repeated focused race/shuffle runs of the bounded WebSocket write test
- Full unit, JSON-RPC integration, HTTP integration, OpenAPI contract, and generated-code quality gates
Full Changelog: v1.6.0...v1.6.1
v1.6.0
Highlights
- Adds controlled bounded HTTP server streams and typed SSE result projections, including reusable stream policy, writer, and request metadata APIs.
- Supports result-view requiredness overrides and preserves optional union absence across code generation and flat-form HTTP decoding.
- Documents raw request-stream bodies correctly in OpenAPI while improving schema deduplication.
- Hardens JSON-RPC batch writes, SSE notification validation, logging, response capture, and invalid transform diagnostics.
Upgrade notes
Regenerate generated clients and servers with loom gen to pick up the new streaming projections, union handling, and transport code. Existing designs remain source compatible; new bounded-stream and requiredness controls are opt-in.
Verification
Release preflight passed lint, unit tests, HTTP and JSON-RPC integration suites, OpenAPI contract/consumer checks, and generated-code quality gates.
Full changelog: v1.5.1...v1.6.0
v1.5.1
Highlights
- Generated JSON-RPC
Server.ServeHTTPnow always enters through the effective handler chain, so runtime CORS and middleware installed withServer.Useapply to mounted requests and downstream transport extensions. - Raw HTTP, mixed HTTP/SSE negotiation, and WebSocket dispatch remain internal, preserving streaming, session, cancellation, and transport-policy composition without recursion.
- Generated OPTIONS routes remain terminal and use the route-local allowed-method set.
Upgrade notes
Regenerate JSON-RPC server code after upgrading. Custom mounts and generator extensions should route actual requests through the generated server ServeHTTP entry point. No DSL changes are required.
Verification
The release passed lint, uncached unit tests, JSON-RPC and HTTP integration suites, OpenAPI contract checks, generated-code-quality checks, and GitHub race/shuffled-order CI.
Full Changelog: v1.5.0...v1.5.1
v1.5.0
Highlights
Runtime-configured CORS
RuntimeCORS()lets HTTP and JSON-RPC designs declare that browser-origin policy comes from deployment configuration rather than generated literals.loomhttp.NewRuntimeCORSPolicyvalidates exact and regular-expression origins, credentials, methods, headers, exposed headers, and max age, then snapshots the policy into an immutable value supplied to generated server constructors.- Generated actual-request and preflight handling now applies that runtime policy consistently across ordinary HTTP, HTTP SSE, JSON-RPC POST, and mixed HTTP/SSE servers.
- OpenAPI publishes
x-loom-cors: {runtime: true}without leaking deployment-specific origins.
Leaner mixed JSON-RPC SSE servers
- Mixed HTTP/SSE JSON-RPC services now emit only the active unified
ServeHTTPnegotiation path and endpoint stream implementation. - The unreachable SSE-only
handleSSEpath and service-levelsse.goartifact are no longer generated for mixed services. - Eager GET stream opening is emitted only for the real
events/streamlistener, removing impossible branches from other SSE methods.
Safer and more observable SSE delivery
- Generated HTTP SSE responses default
X-Accel-Bufferingtonoso reverse proxies do not buffer incremental events. Caller-supplied header values remain authoritative. - JSON-RPC
SendAndCloseon ID-less streams keeps its protocol-correct response suppression, but now emits the low-cardinalitystream_final_response_suppressedtransport event so discarded final values are observable. - Generated GoDoc and DSL guidance now make the ID-scoped final-response contract explicit: raw GET
events/streamimplementations must useSendfor every value that should reach the client.
Upgrade notes
- Regenerate HTTP and JSON-RPC transports with
loom gento receive the SSE header, observability, and mixed-server cleanup changes. - Mixed JSON-RPC regeneration intentionally deletes the obsolete generated
server/sse.go; do not retain that file manually. - Designs that opt into
RuntimeCORS()gain aloomhttp.RuntimeCORSPolicyparameter on the generated server constructor. Load deployment configuration in application startup, callloomhttp.NewRuntimeCORSPolicy, handle its validation error, and pass the resulting value to the constructor. - Existing static
CORSdesigns and designs without CORS retain their existing constructor signatures and behavior. - WebSocket origin authorization remains separate from CORS; continue configuring the upgrader's
CheckOriginpolicy explicitly.
Verification
- Release preflight:
lint,test-release,integration-test,openapi-contract, andgenerated-code-quality. - Focused generated-module compile tests cover runtime CORS for HTTP, SSE, JSON-RPC, and mixed transports.
- Checked-in HTTP and JSON-RPC SSE fixtures were regenerated and exercised by the transport integration suites.
Full changelog: v1.4.1...v1.5.0
v1.4.1
Highlights
Runtime fixes
grpc.NewStatusError(codes.OK, err, ...)no longer returnsnil: a status built withcodes.OKyields a nil error, which silently swallowederr. The code is now replaced withcodes.Unknownso the error always survives.- The HTTP middleware traced client (
WrapDoer) no longer panics when a request context carries a trace ID without a span ID (or non-string trace values). It now propagates whatever trace headers are present and skips the rest. - Restored the
dsl.APIKeyGoDoc, which had been reduced to a stray comment fragment.
Test-suite overhaul
This release ships the results of a full test-suite audit (see TEST_AUDIT.md in the repo):
- Coverage now tracks risk instead of inverting it: gRPC runtime 39.6% → 93.3%,
clue/log12.2% → 100%, middleware 40.7% → 83.1% / 94.4%, direct DSL coverage for the security/SSE/CORS/streaming clusters, the JSON-RPC decoder sections file 29.1% → 100%, and the pulse Redis runtime now runs against miniredis (rmap/streaming/pool at ~72–75%). - The raw GET
events/streamSSE listener finally has behavioral coverage. The pinned contract:Sendvalues arrive as JSON-RPC notifications; theSendAndClosevalue is intentionally not delivered on ID-less GET listeners (the stream just closes). Whether that should change is tracked in #146. - ~300 implementation-coupled substring assertions were migrated to 76 golden files with scripted no-lost-assertion gates, so cosmetic emitter changes no longer break dozens of tests.
- A new
make test-racegate (-race -shuffle=on) runs in CI on every push/PR. Its first runs caught and fixed real data races (unsoundt.Parallelagainst the process-global DSL state) and order-coupled tests (OTel globals,expr.Rootleakage, hardcoded X-Ray UDP ports).
CI restructure
- Windows is no longer part of the per-PR pipeline (it only ran unit tests while being the slowest job); an on-demand
windows-canaryworkflow replaces it (gh workflow run windows-canary.yml). Per-PR critical path: 455 s → 234 s. - The npx-based OpenAPI consumer smoke moved out of
make test(no Node or network needed locally); the dedicatedopenapi-contractjob owns it. make cleanremoves the build artifacts integration runs leave behind.
Upgrade notes
- No generated-code changes: regeneration of existing designs is not required.
- The only behavior changes are the two runtime fixes above; if you relied on
NewStatusError(codes.OK, ...)returning nil (unlikely and previously a silent error drop), the call now returns acodes.Unknownstatus error. github.com/alicebob/miniredis/v2was added as a test-only dependency of this module; consumers of the library are unaffected at build time.
Verification
make lint,make test,make test-race(race + shuffled order),make integration-test,make openapi-contract, andmake generated-code-qualityall green locally and in CI (runs onmainthrough commit 93edcbb).- Release preflight (
lint test-release integration-test openapi-contract generated-code-quality) passed as part ofmake release.
Full changelog: v1.4.0...v1.4.1
v1.4.0
Highlights
Safer streaming lifecycles
- Fixed HTTP and JSON-RPC WebSocket close behavior before upgrade, made connection access race-safe, and preserved successful frame operations when cancellation races completion.
- Prevented Pulse readers and schedulers from arming blocking work during shutdown, eliminating close-time hangs and ownership races.
JSON-RPC SSE contracts
- Added design-owned CORS generation for JSON-RPC HTTP, SSE, mixed, and WebSocket servers.
- Added
SSENotificationMethod(...)for design-controlled intermediate notification methods. - Intermediate SSE notifications now default to
<service>/stream.event; generated clients and the integration harness are aligned withmessageevents while remaining compatible with legacy/default SSE frames. - Omitted JSON-RPC
paramsnow decode as an empty object for all-optional payloads. Last-Event-IDpropagation now uses the shared typedloomhttp.LastEventIDKeycontract.
Transport correctness and portability
- Normalized HTTP path parameters exactly once, avoiding double escaping and decoding.
- gRPC
Anyconversion failures now return descriptive errors instead of silently producing nil values. - Fixed generated path handling and golden comparisons across Windows and Unix.
- Updated framework dependencies and made CI tool installation and generated-code lint caching deterministic.
Upgrade notes
Regenerate generated clients, servers, and transport types with Loom v1.4.0.
Raw JSON-RPC SSE consumers should note that the default intermediate notification method changed from the request method to <service>/stream.event. Designs that must retain an existing wire method can set it explicitly with SSENotificationMethod("existing/method").
Generated SSE event types and gRPC conversion error paths may change observable behavior, but no existing DSL entry points were removed.
Install the release with:
go install github.com/CaliLuke/loom/cmd/loom@v1.4.0Verification
The release passed make release VERSION=v1.4.0, including lint, uncached release tests, HTTP and JSON-RPC integration tests, OpenAPI contract and consumer checks, and generated-code quality checks on representative HTTP, gRPC, and JSON-RPC fixtures.
Full changelog: v1.3.2...v1.4.0
v1.3.2
Highlights
- Fixed generated Go package collisions when pattern validations were emitted into multiple files. Pattern variables are now named uniquely per generated file.
- Restored correct HTTP error responses for WebSocket endpoints before upgrade. Authentication, validation, and service failures are encoded normally instead of becoming empty HTTP 200 responses.
Upgrade notes
Regenerate affected services with Loom v1.3.2. Generated validation variable names may change, but there are no DSL or runtime API migrations.
Verification
The release passed Loom release preflight, including lint, unit tests, integration tests, OpenAPI contract checks, and generated-code quality checks.
Full changelog: v1.3.1...v1.3.2