Audience: release consumers and maintainers who need dated behavior changes, upgrade notes, and package-tied compatibility acknowledgements.
| Need | Current guidance |
|---|---|
Exact release commands and supported API_BASE_REF |
Use docs/release-runbook.md; do not maintain a second baseline table here. |
| Concise user-facing summary by published version | Use CHANGELOG.md; update it with every release tag. |
| User-visible behavior, migration notes, and compatibility acknowledgements | Add dated entries in this file. Keep historical entries historical unless later guidance would otherwise mislead readers. |
| Stable surface changes | Update VERSIONING.md, package docs, compatibility docs, release notes, and docscheck coverage together. |
| Supported-adapter or selected contrib drift | Run the contrib drift and release-note review gates with the release baseline from the runbook. |
| Generated service upgrade compatibility | make generated-upgrade-compat-check defaults to v3.0.0 v3.1.2; the script, docs/reference-service.md, and docs/release-runbook.md are the checked sources. |
Every dated release entry should use one or more of these categories when the change is present:
| Category | Use when the release includes |
|---|---|
| Breaking | Source-incompatible API, module, config, generated-file, or runtime contract changes. |
| Behavior | User-visible runtime behavior, response shape, validation, persistence, or default changes. |
| Security | Security fixes, hardening, bypass removal, vulnerability disposition, or sensitive default changes. |
| Docs | Documentation-only changes that affect adoption, upgrade, release, or operations guidance. |
| Dependencies | Dependency upgrades, removals, replacements, vulnerability-driven changes, or imported-only risk dispositions. |
| Generated scaffold | Generator CLI behavior, templates, scaffold runtime assets, generated Makefile targets, or reference-service compatibility. |
| Migration | Upgrade steps, compatibility notes, deprecations, replacement paths, or required operator action. |
For stable surface changes, deprecations, or compatibility-sensitive updates,
keep this file focused on user-visible behavior and upgrade notes. The command
source of truth is docs/release-runbook.md.
- Choose one or more release note categories from the taxonomy above before adding the dated entry; do not bury breaking, behavior, security, dependency, generated scaffold, or migration impact under generic prose.
- Update
VERSIONING.md, public docs, and package docs that describe the affected stability contract. - Update
scripts/apicheck.shand docscheck coverage when the stable package list or compatibility-sensitive manifest changes. - Update
docs/ports-surface.md,docs/v3-compatibility-roadmap.md, release notes, and upgrade notes when compatibility-sensitive ports or legacy stable surfaces change. - Add release notes and upgrade notes that describe user-visible behavior, migration paths, and compatibility impact.
- Run release evidence through the runbook path;
docs/release-runbook.mdowns the current supportedAPI_BASE_REFbaseline and exact commands, whilemake finalizeandmake audit-checkare local/reviewer gates. - Run
make contrib-api-drift-reportwith the same release baseline when selected contrib adapters or integrations change exported APIs; selected packages come fromdocs/contrib-api-drift-packages.txt, supported-adapter incompatible drift is gate-enforced, and this does not make contrib stable. - Run
make contrib-release-notes-checkwith the same release baseline when supported contrib adapter, integration, middleware, bootstrap, telemetry, production generator CLI behavior files, or runtime assets change. - Supported-adapter contrib packages remain outside the stable core API promise, but incompatible public API drift in that tier must be treated as gate-enforced and resolved with compatibility, reclassification, or a major-release policy decision.
- If there is incompatible report-only contrib drift, add an explicit release note or upgrade note acknowledgement tied to the affected package. This does not make contrib stable.
- Update
docs/vulnerability-dispositions.tsvwhen imported-only vulnerability IDs change, expire, or receive upgraded dependencies. - Update
docs/contrib-api-drift-dispositions.tsvwhen current contrib drift packages or incompatible drift status changes. - Use clean publication evidence with the explicit baseline command from
docs/release-runbook.md; reserveALLOW_DIRTY_RELEASE_EVIDENCE=1for local dirty-tree audit evidence that is not acceptable before publishing. First v3 major-release evidence may useAPI_BASE_REF=v2.1.0only as documented v2-to-v3 transition evidence. - Use
docs/release-manifests.mdwhen interpretingdocs/package-classification.tsv,docs/contrib-api-drift-dispositions.tsv, anddocs/vulnerability-dispositions.tsv.
- The v4 release-identity review verifies root
v4.0.1as the sole root-module baseline. UseAPI_BASE_REF=v4.0.1for v4 root release checks. v4.0.0,contrib/v4.0.0, andcontrib/v4.0.1are withdrawn. Contrib consumers must wait for a new paired repair release; do not substitute the root tag for the withdrawn contrib module.
contrib/adapters/chi.Middleware.RealIPnow ignores untrusted forwarding headers and leaveshttp.Request.RemoteAddrintact. This removes the spoofablemiddleware.RealIPbehavior identified by the updated chi dependency.- Reverse-proxy deployments must obtain the resolved client address through
middleware.GetClientIP(r.Context())and applychi.ClientIPFromXFF(trustedCIDRs...). The helper trusts only the configured proxy CIDRs and never mutatesRemoteAddr.
- Published the v4 root and contrib module paths with the mechanical import replacements documented in migration/v4.md.
- Reduced root
portsto generic logger, clock, and identifier contracts; endpoint, middleware, authorization, HTTP, and platform contracts now have package-local or contrib-owned v4 destinations. - Moved JWT/JWK middleware, shared auth internals, OAuth2 helpers, and auth test support into contrib. Root v4 has no direct JWT/JWK requirements; issuer, audience, algorithm, JWKS, and trusted-proxy bypass validation behavior is unchanged.
- Added workspace, root/contrib module, generated-scaffold, reference-service,
root-port ledger, API transition, dependency, coverage, race, fuzz, lint,
vulnerability, and
gosecrelease evidence.
- Added package-local endpoint aliases for
health.Checker,health.ManagerContract,health.DetailedManager,health.CachedManager,health.RouteRegistrar,docs.Provider,docs.ManagerContract,docs.HTMLModeProvider, anddocs.RouteRegistrar. They preserve exact v3 source compatibility with their rootportscounterparts while giving new health and documentation integrations a consuming-package import path. - Added package-local idempotency store aliases:
idempotency.Store,idempotency.ReservationReleaser, andidempotency.ReleasableStore. New integrations can adopt them after updating to a root version that contains these aliases; they retain exact v3 source compatibility with the root contracts. - Added package-local authorization aliases:
authorization.Authorizer,authorization.AuthorizerFunc,authorization.PolicyEngine,authorization.PolicyRequest, andauthorization.PolicyDecision. They do not change default-deny, owner, tenant, or policy-engine behavior and remain source-compatible with the v3 root contracts. - Deprecated the broad root
portscontracts that now have package-local aliases: rate limiting, idempotency stores, authorization and policy, health endpoint interfaces, and docs endpoint interfaces. They remain available throughout v3;docs/deprecations.mdrecords each replacement and the v4 removal horizon. - Published an accountable v4 scope ledger in
docs/v4-plan.md. Each keep, narrow, split, and removal decision now names an owner, replacement direction, and migration evidence required before a v4 API change. - Assessed provider extension-module candidates using ownership, dependency, contract, realism, and drift evidence. No family is approved for extraction without independent adoption or family-specific release-cadence evidence.
- Clarified that CLI and scaffold behavior releases through contrib tooling ownership and release-note review, never through the root stable API promise.
- Published an AST-verified root-port migration ledger with all current exports, consumers, implementation evidence, deprecation state, and v4 dispositions.
- Updated contrib
github.com/jackc/pgx/v5fromv5.9.0tov5.9.2andgithub.com/yuin/goldmarkfromv1.7.16tov1.7.17to remove the calledgovulncheckfindingsGO-2026-5004andGO-2026-5320. The update does not change api-toolkit's public API;adapters/pgxpoolremains a supported contrib adapter andemail/markdownremains experimental.
- The module paths are now
github.com/aatuh/api-toolkit/v4andgithub.com/aatuh/api-toolkit/contrib/v4. - Provider-shaped billing exports were removed from root
ports; usegithub.com/aatuh/api-toolkit/v4/compat/billingfor the hosted-checkout compatibility model or define app-owned billing ports. ports.DatabasePool.Stat,ports.DatabaseStats,ports.SnapshotDatabaseStats, and the publicresponse_writerpackage were removed. Useports.DatabasePoolSnapshotProvider,ports.SnapshotDatabasePoolStats, adapterStatSnapshot()methods, andhttpx.- Idempotency middleware now requires token-aware release through
ports.IdempotencyReservationReleaser. authz.NewRequireRoleMiddlewarenow validates at construction time and returns(*RequireRoleMiddleware, error).- List endpoint helpers keep the checked parser APIs:
ParseListQueryChecked,DefaultFilterParserChecked, andDefaultSortParserChecked.
- Added
middleware/ratelimit.Limiteras a package-local v3 migration shim overports.RateLimiter. Existingports.RateLimiterusers remain source-compatible, while new rate-limit adapters can move imports toward the consuming middleware package before v4 shrinks broad root ports. - Updated
docs/deprecations.mdso the active register covers the existing source-deprecatedmiddleware/timeout.Newandmiddleware/trace.Useshims with replacements, removal horizon, snippets, and release-note pointers.
- Added experimental
github.com/aatuh/api-toolkit/v4/compatkitdownstream compatibility test support. Services can run readiness, version, Problem Details, OpenAPI compatibility, and custom HTTP checks against an in-process handler or explicit base URL without promoting the package to the stable API surface.
- Published
v3.1.2from the currentmasterrelease tag evidence and advanced the v3 patch/minor release baseline examples tov3.1.2. - Added the paired
contrib/v3.1.2module tag because the contrib module changed in the release. make generated-upgrade-compat-checknow defaults to the published baseline matrixv3.0.0 v3.1.2;GENERATOR_REFremains as the single-ref compatibility alias.
- Added focused behavior tests for
endpoints/docs,httpx/identity,httpx/recover,middleware/json,middleware/maxbody,middleware/querylimits, andsecurityprofile, then added package-specific coverage floors for those stable HTTP/security surfaces. - Added direct response-recorder behavior tests for
contrib/middleware/metrics,contrib/middleware/oteltrace, andcontrib/middleware/requestlog, including informational statuses, committed-state behavior, optional response-writer interface forwarding, and unsupported interface fallbacks. Coverage floors now protect those observability middleware packages. - Replaced direct sleep-based assertions in timeout, security-profile, outbound HTTP retry, and transaction cleanup tests with context deadlines or channel synchronization so the same behavior is checked with less timing risk.
- Hardened the hard-timeout capture path so handler writes are rejected as soon
as the request deadline channel is closed, then added
make timeout-determinism-checkfor repeated normal and race evidence around late-write rejection. - Added
docs/supported-adapter-test-realism.tsvand docscheck coverage so every supported adapter declares default PR evidence, scheduled/manual evidence, and whether that evidence is direct-unit, fake DB, miniredis, hermetic fixture, or real-service-backed. make coverage-checknow writes.ci-result/coverage/summary.mdso CI can append root/contrib coverage totals to the GitHub job summary without making aggregate coverage the test-quality score.- Added
make reference-service-coverageas non-Docker generated-service coverage evidence. It writes.ci-result/coverage/reference-service.funcand.ci-result/coverage/reference-service-summary.mdseparately from toolkit root/contrib coverage thresholds. - Docscheck now keeps the checked-in reference service package test inventory explicit, including package-level rationales for generated or entrypoint packages that intentionally do not carry direct tests.
make generated-upgrade-compat-checknow acceptsGENERATED_UPGRADE_COMPAT_REFSand defaults to checking bothv3.0.0andv3.1.2;GENERATOR_REFremains as a source-compatible single-ref alias.- Generated upgrade compatibility evidence now writes one log per generator ref
plus
.ci-result/generated-upgrade-compat/status.tsv. - Full-profile resource generation tests now prove the generated
projectreplacement path with required/default/enum fields, filters, deterministic sorts, OpenAPI/client checks, contract checks, andresource-checkevidence. - Full-profile docs and generated READMEs now state that sample
widgetsare app-owned starter domain code meant to be replaced or complemented by product resources. - Added
make reference-service-evidence, which records non-blocking reference-service proof under.ci-result/reference-service/, with optionalREFERENCE_SERVICE_DOCKER=1andREFERENCE_SERVICE_MINIO=1runtime evidence. - Added a reference-service adoption evidence template for setup time, upgrade results, OpenAPI/client checks, tenant isolation, idempotency, backup/restore, load-smoke notes, and known pain points.
- Removed the temporary
.next_steps.mdrelease checklist after publishingv3.1.0; future release baseline guidance now lives in the release runbook. - Added
examples/reference-saas-apias a checked-insaas-api-fulladoption proof service with local workspace replacements, typed client output, OpenAPI/contract assets, Docker integration assets, deployment starters, and observability assets. - Added
make reference-service-checkas optional non-Docker evidence for the checked-in reference service. It stays outside defaultfinalize. - Generated
saas-api-full.gitignorefiles no longer ignoreinternal/client/apiclient, so the checked-in typed Go client can be tracked by generated services.
contrib/adapters/validationnow usesgithub.com/aatuh/validate/v3@v3.0.7instead ofgithub.com/go-playground/validator/v10.- Validation tags in toolkit examples now use the validate v3 grammar, such as
validate:"string;required;email"andvalidate:"int;min=1". - Field errors now preserve validate v3 JSON field paths and stable error codes
while continuing to avoid raw submitted values in error strings. The
deprecated
ValidationError.Valuefield is retained for source compatibility but is no longer populated by the adapter. NewPlaygroundValidatorremains as a deprecated source-compatible alias, but it no longer constructs a go-playground-backed validator. UseNewValidateValidatorfor new code.
- Added
make generated-upgrade-compat-check, an opt-in generated-service upgrade compatibility signal that generatessaas-api-fullfrom the prior v3 baseline, replaces toolkit dependencies with the workspace, and runs generated tests, OpenAPI, client, and contract checks. This stays outsidefinalize. - Raised the JWT middleware package coverage floor after adding behavior tests for valid subject propagation, skip-header enforcement, nil/disabled handler behavior, safe close behavior, and JWKS health checks.
- Raised the health endpoints package coverage floor after adding behavior tests for public liveness/readiness separation, dependency state transitions, timeout mapping, public detail redaction, admin-only detailed health access, dependency checker options, and scheduler callbacks.
- Raised the OpenAPI validation middleware coverage floor after adding behavior tests for option constructors, OpenAPI file loading, route failure Problem Details, request validation field mapping, response validation error hooks, streaming opt-outs, large-response bypasses, and response buffering limits.
- Raised webhook delivery and Postgres webhook delivery adapter coverage floors after adding behavior tests for signing, endpoint policy, retry classification, safe error surfaces, tenant mismatch rejection, replay safety, attempt recording, secret resolution, and readiness health.
- Raised the pgxpool adapter coverage floor after adding behavior tests for constructor validation, bounded startup contexts, database readiness mapping, plain-value snapshots, legacy stats wrappers, acquire failures, and close idempotence.
- Added a docscheck gate that every
supported-adaptercontrib package has direct tests, package docs, a behavior-contract row, and release drift coverage before it can retain the supported-adapter classification. - Added a manifest-driven adapter maturity review to the production-readiness docs so supported adapters are visible as evidence-complete and experimental packages are clearly not promoted.
- Updated the release workflow provenance attestation action from the older
actions/attest-build-provenancegeneration to a pinned v4.1.0 commit while preserving release artifact verification semantics. - Updated generated lean and full scaffold GitHub Actions templates to pinned
actions/checkoutv6.0.2 andactions/setup-gov6.4.0 commits. - Added
make actions-auditand contract coverage for pinned GitHub Actions workflow refs, stale action comments, and generated workflow template versions; it runs inmake audit-checkand remains non-mutating. - Tightened README and production-readiness positioning so api-toolkit is explicitly scoped to conventional HTTP/JSON API infrastructure, not a universal backend platform, and generated code is app-owned.
- Aligned the release runbook with end-game proof targets by making
actions-audit,coverage-check, generated upgrade compatibility, generated integration, and reference-service evidence visible to release reviewers while keeping Docker-backed checks opt-in. - Tightened the optional GitHub governance verifier so release tag protection
covers both root
v*tags and contrib modulecontrib/v*tags. - Removed the local root-module
replacedirective fromcontrib/go.modso the contrib CLI can be installed withgo run github.com/aatuh/api-toolkit/contrib/v4/cmd/api-toolkit@vX.Y.Z. - Added
docs/coverage-hardening-backlog.mdto make the next JWT, health, pgxpool, OpenAPI middleware, and webhook delivery coverage floor increases conditional on behavior-test evidence rather than numeric threshold churn. - Raised maturity evidence for high-risk v3 surfaces with additional JWT, OpenAPI validation, and bootstrap tests. The package coverage gate now keeps the OpenAPI validation middleware and bootstrap floors aligned with the new observed coverage.
- Promoted production-relevant contrib packages to
supported-adapterafter direct tests, package docs, behavior-contract rows, and drift coverage were confirmed:contrib/adapters/httpclient,contrib/adapters/envvar,contrib/config,contrib/adapters/validation,contrib/adapters/migrate,contrib/migrator, andcontrib/scheduler/postgres. - OPA and Cedar policy adapters now use a shared policy-engine contract for
provider-neutral request mapping, allow/deny decisions, malformed input
failures, and safe error surfaces, and are promoted to
supported-adapter.
- Contrib packages promoted to
supported-adapterremain outside the stable root SemVer promise. Incompatible supported-adapter drift is now release-gated and must be release-noted.
-
docs/full-service-scaffold.mdnow defines the plannedsaas-api-fullproduction profile contract, including Postgres + Redis defaults, tenant resources, durable async/outbox behavior, audit events, webhook delivery, OpenAPI 3.1, typed Go client output, opt-in Docker integration checks, and base Kubernetes assets. -
scripts/contrib_release_notes_check.shand its contract tests now require release-note coverage for futuresaas-api-fullfull-profile runtime assets undercontrib/cmd/api-toolkit, including generated Kubernetes YAML and other scaffold templates. -
api-toolkit new servicenow supports an initial--profile saas-api-fullscaffold with API-key auth, hexagonalinternal/domain,internal/app,internal/adapters/postgres, andinternal/httpapiboundaries, Postgres migrations for tenant/platform tables, Docker Compose Postgres/Redis assets with optional MinIO, Kubernetes starter manifests, OpenAPI golden checks, contract lint/diff/client-check targets, checked-in Go client output, and generated HTTP smoke tests for readiness, OpenAPI, auth failure, validation failure, idempotent create replay, and ETag conflicts. -
api-toolkit new service --profile saas-api-fullnow accepts repeatable--with stripe-billing|resend-email|clerk-webhooksflags. Selected provider workflows generate app-ownedinternal/providersstarter packages, provider docs, env examples, manifest entries, fake-provider tests, tenant-scoped audit behavior, and webhook/signature verification boundaries without adding provider-specific imports to the toolkit root module. -
The async, audit, cache, objectstore, webhookdelivery, OIDC middleware, OIDC integration, and their Postgres/Redis/S3 adapters now have supported-adapter classification, package contract rows, drift-gate coverage, and release-note requirements. Postgres audit, operation, outbox, and webhook delivery stores also expose readiness health checkers, and
contrib/async/asynctestadds a reusable async store contract suite for adapter implementations. -
api-toolkit --help,api-toolkit -h,api-toolkit help, and equivalent subcommand help forms now return usage with exit code0; unknown commands continue to exit2. -
api-toolkit clients typescript --style fetchnow generates a browser/stdlibfetchTypeScript package for the same supported OpenAPI subset as the typed Go client: JSON bodies, path/query/header params, API-key and bearer auth, Problem Details errors, nullable fields, enums, and raw response access.api-toolkit new service --profile saas-api-full --client typescriptadds the checked-in TypeScript client package andclient-ts-checktarget while keeping the existing generated Go client path source-compatible. Generated TypeScript configs include DOM iterable fetch types, andclient-ts-checkruns a local TypeScript build whennode_modulesis already present. -
api-toolkit ops observability --profile saas-api-fullnow emits a bounded label Grafana/Prometheus/runbook bundle for the full scaffold, andapi-toolkit deploy helmplusapi-toolkit deploy terraform --cloud awsgenerate deployment starters for API, worker, migration, admin service, dependency references, and AWS Postgres/Redis/S3 primitives. Generated full services now includecmd/assetcheckplusmake observability-check,make deploy-check, andmake asset-checkso those starter assets are validated offline without Helm, Terraform, jq, or network access. Release evidence now records those generated asset checks infull_profile_scaffold_evidence.asset_validation. -
Generated
saas-api-fullmigrator commands now includeplan,verify, and a guardeddowncommand. Down migrations require both--allow-dangerous-downandALLOW_DANGEROUS_MIGRATION_DOWN=true, and remain documented as local/schema-teardown only. When both guards are present, the generated command now delegates tobootstrap.RunDownand reverts one latest applied migration through the contrib migrator. -
api-toolkit generate resourcenow accepts the v2 field and route-shaping flags--field,--filter,--sort,--admin,--relationship, and--object-field, validating the field DSL before mutating generated projects. Generated resources now wire exact-match list filters and allow-listed deterministic sorts through HTTP query parsing, application services, parameterized Postgres queries, OpenAPI parameters, generated typed clients, and partial Postgres indexes. Relationship flags add<name>_idfields, and object-backed fields must end in_keyand expose only object keys, not payloads.--adminnow mounts a generated admin-list endpoint under/admin/<plural>on the admin router only, protected byX-Admin-Keyand an explicit tenant selector. -
Provider workflow scaffolds now include
cmd/provider-replay, and generated provider-check runs package tests plus deterministic replay validation for checked-in Stripe, Resend, and Clerk fake fixtures. Live provider checks remain gated byRUN_PROVIDER_LIVE_CHECKS=true. -
api-toolkit contracts changelogandapi-toolkit contracts impactnow report OpenAPI operation additions/removals and machine-readable breaking client impact for release review. Contract lint and impact checks now also cover OpenAPI 3.1 composition review metadata, streaming and binary response metadata, callback/webhook metadata, schema default changes, enum widening and narrowing, and oneOf/anyOf/allOf composition changes. -
api-toolkit new service --profile saas-web --auth session|oidc-sessionnow emits a separate browser/session starter so API-first profiles stay unchanged. The generated profile includes cookie security defaults, memory and Redis session-store boundaries, guarded production startup validation, CSRF middleware, OIDC callback state validation, browser-safe CORS, and session fixation tests without adding session dependencies to the root module. -
api-toolkit new service --profile saas-api-full --with entitlementsnow emits provider-neutral generated app code for plans, features, quotas, usage counters, OpenAPI entitlement routes, Postgrestenant_entitlementsandbilling_mappingspersistence, and billing-provider composition guidance. The workflow composes with--with stripe-billingby updating app-owned billing mappings before entitlement changes, without adding Stripe-shaped ports to core. -
github.com/aatuh/api-toolkit/contrib/v4/entitlementsnow provides provider-neutral feature and quota contracts, low-cardinality decisions, reusable store contract tests, and HTTP enforcement middleware that avoids exposing tenant or billing identifiers in Problem Details responses. -
Release evidence now expands
full_profile_scaffold_evidencewith explicit fields for OpenAPI 3.1 full scaffold output, typed client generation, resource generator checks, provider-flag generation, worker wiring, generated integration workflow assets, and opt-in Docker integration status. The focusedfull-profile-scaffold-checktarget now covers provider workflow generation and resource generation in addition to the full scaffold auth modes. -
Generated
saas-api-fullservices now include tenant domain and application services for organizations, memberships, invitations, role checks, and invitation acceptance. The generated service hashes invitation tokens before storage, returns the raw invitation token only from the create-invitation use case, and includes generated unit tests for owner membership, role failures, wrong-token failures, and single-use invitation acceptance. -
Generated
saas-api-fullHTTP routers now expose organization create/list, member list, invitation create, and invitation accept routes with OpenAPI contracts, generated Go client methods, idempotency metadata, tenant policy metadata, and generated HTTP tests for role failures and token replay. -
Generated
saas-api-fullservices now include API-key lifecycle management for organization-scoped create/list/revoke, scoped permissions, one-time raw secret return, non-secret key prefixes, peppered SHA-256 hash storage, last-used tracking on verification, and generated OpenAPI/client coverage. -
api-toolkit new service --profile saas-api-full --auth jwt|clerk|oidcnow emits matching bearer-auth runtime wiring, generated auth tests, tenant claim checks, scope checks, and BearerAuth OpenAPI security instead of falling back to API-key-shaped full-profile router code. -
Generated
saas-api-fullservices now include an async widget import workflow using202 Accepted,Location/Retry-After, tenant-scoped operation polling atGET /operations/{id}, replay-safe idempotency, a generated worker service over the contrib async store/handler contracts, and OpenAPI/client coverage forcreateWidgetImportandgetOperation. -
Generated
saas-api-fullservices now wire optional Postgres runtime startup checks: whenDATABASE_URLis set, generated code opens a pgx pool, pings it, verifies required platform tables, closes the pool on shutdown, and reflects database failures through public readiness and admin detailed health. -
Generated
saas-api-fullservices now usebootstrap.NewAPIServiceas the composition root for public/admin listeners, strict SaaS middleware order validation, safe system endpoint mounting, graceful shutdown, and async worker lifecycle. The full profile now exposes/livezseparately from/readyz, keeps liveness process-only, moves detailed health/metrics/pprof to the admin listener whenADMIN_ADDRis set, and enables runtime OpenAPI request validation by default with response validation enabled in development/test or byOPENAPI_RESPONSE_VALIDATION=true. -
Generated
saas-api-fullservices now include an in-process audit recorder and write-route hooks for organization, invitation, API-key, widget, and async import actions, with generated tests proving audit metadata redaction and no raw API-key secret leakage. -
Generated
saas-api-fullservices now include outbound webhook event catalog, endpoint create/list, delivery list, and delivery replay routes; widget writes enqueue tenant-scoped pending deliveries for subscribed endpoints, generated OpenAPI/client output covers those operations, and tests prove webhook signing secrets are returned only at endpoint creation. -
Generated
saas-api-fullOpenAPI documents now opt into OpenAPI 3.1 throughspecs.NewRegistryWithOptions(... OpenAPIVersion31)while the leansaas-apiscaffold keeps the existing OpenAPI 3.0 default. -
Generated
saas-api-fullservices now include a generated cache service, in-memory local cache store, Redis cache adapter,CACHE_STOREconfiguration, cache readiness composition, and cached webhook event catalog responses with generated tests for TTL, cloning, Redis address validation, and cache hits. -
Generated
saas-api-fullservices now include tenant-scoped object storage routes and application services with strict key, content-type, and size validation, OpenAPI/client coverage, audit hooks, and tests proving object payloads are not exposed in list/create responses or validation problems. -
Release evidence now records
full_profile_scaffold_evidence, andmake release-checkincludes a focusedmake full-profile-scaffold-checktarget so the generatedsaas-api-fullservice, OpenAPI/contract workflow, and generated Go client are explicit release signals. Generated Docker integration checks remain opt-in and are reported separately through the non-blocking integration evidence status. -
Generated
saas-api-fullintegration-checknow uses a dedicated script that starts Postgres and Redis, applies the generated migration, runs generated unit tests, starts the API on localhost, and performs HTTP smoke checks for readiness, OpenAPI, authentication failure, tenant membership, managed API-key authentication, idempotent widget writes, ETag conflict handling, async operation polling, outbox completion/retry behavior, webhook delivery/replay, object write/readback, audit writes, admin detailed health, admin metrics, admin pprof, and public admin-route isolation before tearing Docker volumes down. SetINTEGRATION_OBJECT_STORE=s3to have the script start the optional MinIO profile, initialize the generatedapi-objectsbucket, and run the same object checks through the S3-compatible adapter. Fresh generated checkouts now materialize.envfrom.env.examplebefore invoking Docker Compose, and the generated Postgres volume mount uses the PostgreSQL 18-compatible/var/lib/postgresqlparent directory. Generated full-profile Makefile, Dockerfile, and integration checks now hydrate module sums withgo mod tidybefore build or test commands, and generatedgo.modfiles use the installed toolkit release version instead of pinning the stale v2.1.0 baseline when the CLI is installed from a SemVer tag. The generated integration script now feeds SQL through stdin so psql variables are expanded, isolates generated auth tests from integration actor environment variables, uses current-compatible MinIOmc mb --ignore-existingflags, and tears down Compose with the objectstore profile enabled so optional MinIO resources do not remain running after S3 checks. -
Postgres audit and outbox adapters now exercise real-SQL failure paths more closely: audit SQL no longer includes Go comment text, and outbox retry scheduling casts the retry base timestamp before adding interval backoff.
-
Generated
saas-api-fullwidget services now use an application storage port, and the generated runtime switches to a Postgres widget store whenDATABASE_URLis configured. The store persists widget create/update/delete state in the generatedwidgetstable while preserving the local in-memory default for tests and lightweight development. -
Generated
saas-api-fullAPI-key services now switch to a generated Postgres API-key store whenDATABASE_URLis configured. The store persists only keyed hash bytes, display prefixes, scopes, expiry, revocation, and last-used timestamps; raw API-key secrets are still returned once and are not durable data. -
Generated
saas-api-fulltenancy services now switch to a generated Postgres tenancy store whenDATABASE_URLis configured. The store persists organizations, owner memberships, role checks, invitation token hashes, invitation acceptance, and member listing while keeping raw invitation tokens return-once only. -
Generated
saas-api-fullasync widget imports now switch to generated Postgres operation/outbox wiring whenDATABASE_URLis configured. The app service writes tenant-scoped pollable operation rows, enqueues outbox work, and the generated outbox store leases work through contrib async while keeping failure problems sanitized. -
Generated
saas-api-fullPostgres runtimes now route the shared outbox throughcontrib/async's handler mux, dispatchingwidgets.importto the widget importer andwebhook.deliveryto the outbound webhook deliverer. Webhook attempts are recorded through the generated app/Postgres store boundary with sanitized errors and low-cardinality delivery metrics. -
Generated
saas-api-fullservices now include a dedicatedcmd/workerbinary for background jobs, anASYNC_WORKER_ENABLEDswitch for API processes, Docker Compose worker service wiring, a Kubernetes worker Deployment, and integration-check startup that exercises the worker separately from the public API process. -
Generated
saas-api-fullintegration checks now run a local webhook receiver, prove successful outbound delivery and replay reach it, verify failing webhook endpoints record retryable delivery state, force a poison outbox row intodead_letter, and check receiver/delivery output does not expose the generated signing secret. -
Generated
saas-api-fullservices now emit contrib migrator-compatible*.up.sqlmigrations plus a generatedcmd/migrate up|status|checkbinary. Docker Compose runs a dedicated/migrate -dir /migrations upservice before API/worker startup, the integration script applies and checks migrations throughcmd/migrate, and the Docker image now includes/migrateplus/migrations. -
Generated
saas-api-fullKubernetes assets now include ConfigMap, Secret placeholder, migration Job, worker Deployment, internal-only admin Service, PodDisruptionBudget, HPA, NetworkPolicy, resource requests/limits, non-root security contexts, and/livez//readyzprobes. The generated integration workflow is opt-in throughworkflow_dispatchand scheduled runs instead of default PR CI. -
Generated
saas-api-fullservices now include anapi-toolkit.yamlmanifest andresource-checktarget, andapi-toolkit generate resourcenow supports manifest-gated tenant-scoped CRUD generation inside full-profile projects. The generator adds domain/app/Postgres/httpapi files, a contrib-migrator*.up.sqlmigration, route/OpenAPI contracts, audit hooks, webhook event hooks, OpenAPI golden regeneration, typed Go client regeneration, and fails closed when expected generated anchors are missing. -
Generated
saas-api-fullobject routes now supportOBJECT_STORE=s3via a generated blob-store port and S3-compatible adapter wrapper. Tenant and role checks remain in the app service; object bytes are written, read, and deleted through the contrib S3 adapter with bounded size and content-type policy. -
Generated
saas-api-fullS3 object routes now use a generated Postgres object metadata store whenDATABASE_URLis configured, so tenant-scoped list/get/delete state survives process restarts while payload bytes remain in the object store. -
Generated
saas-api-fullwebhook routes now switch to a generated Postgres webhook store whenDATABASE_URLis configured. Endpoint signing secrets are encrypted withWEBHOOK_SECRET_KEY, delivery history is tenant-scoped, and replay updates the delivery row while requeueing the matching outbox job. -
Generated
saas-api-fullunsafe write routes now use the core idempotency middleware with tenant-aware hashed storage keys. Local scaffolds default to in-memory replay;IDEMPOTENCY_STORE=rediswires the generated Redis adapter for cross-instance replay state. -
Generated
saas-api-fullprotected routes now use the core rate-limit middleware. Local scaffolds default to in-process buckets; production defaults requireRATE_LIMIT_STORE=redisand wire a generated Redis limiter with hashed actor/tenant/route keys. -
Generated
saas-api-fullservices now create a contrib Prometheus recorder, wrap publicnet/httproutes with HTTP metrics middleware, and serve the standard Prometheus handler only behind admin authentication. Generated tests assert request metrics use route-pattern labels and do not expose tenants, actors, API keys, admin keys, or idempotency keys. -
Generated
saas-api-fulladmin routers now mount real Go pprof handlers viapprof.RegisterAdminRoutesinstead of returning a placeholder response. Generated tests assert pprof is absent from the public handler and requiresX-Admin-Keyon the admin handler. -
Generated
saas-api-fullAPI-key auth mode now verifies generated API keys through the generated API-key service when the static bootstrapAPI_KEYdoes not match. Managed keys enforce route scopes, bind requests to their organization, update last-used state, fail after revocation, and keep raw key secrets out of Problem Details. -
Generated
saas-api-fullaudit recording now delegates to the contrib Postgres audit store whenDATABASE_URLis configured, after the generated service has produced event IDs, timestamps, and redaction-safe metadata. Local development keeps the existing in-memory audit recorder. -
specs.NewRegistryWithOptionsnow supports explicit OpenAPI 3.1 output viaspecs.RegistryOptions{OpenAPIVersion: specs.OpenAPIVersion31}while preserving the existingspecs.NewRegistryOpenAPI 3.0 default. -
specsnow includes additive schema helpers for reusable refs, nullable schemas, examples, enum values, struct-tag examples/enums/nullable fields, request/response media examples, and reusable HTTP Problem Details response components. -
api-toolkit clients gonow generates a stdlib-only Go client package from OpenAPI operations, including operation methods, path/query/header request options, JSON request bodies, API-key and bearer auth helpers, and Problem Details error decoding. -
api-toolkit clients go --style typednow generates component schema structs, typed request/response operation methods, typed Problem Details error handling, and raw method escape hatches while preserving the existingrawclient style as the default. -
api-toolkit new service --profile saas-api-fullnow checks in typed Go client output and its generatedclient-checktarget regenerates withapi-toolkit clients go --style typed. -
api-toolkit contracts lint,contracts diff, andclients go --style typednow normalize OpenAPI 3.1 schematypearrays containingnulland schema-levelexamplesbefore parser validation. Contract linting also rejects Go client method, schema type, and parameter identifier collisions that would make typed client output unstable or unbuildable. -
specs.Operationnow includesOperationIDand emits OpenAPIoperationIdvalues so route contracts can carry stable client-visible operation identity. -
routepolicynow includes typed metadata helpers for auth, deprecation, sunset, tenant, idempotency, rate-limit, admin-policy, and Problem Details response contracts, plus operation linting for missing production policy metadata. -
routepolicynow exposes typed metadata readers for auth, deprecation, tenant, idempotency, rate-limit, admin-policy, and Problem Details response contracts. Contract linting now requires unsafe-write tenant and idempotency metadata to be explicitly markedrequired: trueinstead of accepting any extension value. -
routepolicy.LintOperationsandapi-toolkit contracts lintnow fail non-public operations without security metadata and unsafe write operations without tenant, idempotency, rate-limit, and Problem Details policy metadata, while allowing known public readiness, liveness, docs, and version routes. -
api-toolkit contracts lintnow accepts repeatable--public-pathand--admin-pathflags so applications can extend the default public and operator-only path sets without weakening the built-in production checks. -
routepolicy,contracttest, andapi-toolkit contracts lintnow enforce unique OpenAPIoperationIdvalues so generated clients and compatibility reviews can rely on stable operation identity. -
routepolicy.LintOperationsandapi-toolkit contracts lintnow require non-public operations, including safe reads, to document Problem Details error responses. -
routepolicy.LintOperationsandapi-toolkit contracts lintnow fail unsafe write operations that omit request body metadata for POST/PUT/PATCH or omit a documented 2xx success response. -
contracttestnow includes assertions for operation IDs, Problem Details error responses, tenant/idempotency/rate-limit/admin policy metadata, registry-wide operation ID coverage, and conservative OpenAPI compatibility findings. -
contracttestnow includes stricter generated-OpenAPI assertions for expected security scopes, tenant policy source, idempotency header, named admin policy, and sets of Problem Details response statuses. -
contracttest.OpenAPICompatibilityFindingsnow reports tenant, idempotency, rate-limit, admin-policy, and deprecation/sunset route policy drift, matching the stricterapi-toolkit contracts diffbehavior. -
CI now runs
make docs-checkexplicitly and runsmake contrib-release-notes-checkon pull requests against the fetched PR base ref, keeping documentation and supported-contrib release-note governance visible before merge. -
CI pull-request governance now also runs
make contrib-api-drift-reportagainst the fetched PR base ref, so supported-adapter incompatible drift fails before merge without making contrib part of the stable core API promise. -
make contrib-release-notes-checknow reviewsgithub.com/aatuh/api-toolkit/contrib/v4/cmd/api-toolkitbehavior files in addition to supported adapters, integrations, middleware, bootstrap, and telemetry, so scaffold and contract-tooling behavior changes require release-note coverage. -
github.com/aatuh/api-toolkit/contrib/v4/bootstrapnow exposesAPIServiceandAPIServiceConfigas a supported composition root for generated services, with safe admin-wrapper system endpoint mounting and startup checks. -
github.com/aatuh/api-toolkit/contrib/v4/bootstrap.APIServiceConfignow acceptsAdminAddrandAdminRouterfor a separate admin listener, andAPIService.AdminHandler()exposes the composed admin handler for tests and custom server wiring. -
github.com/aatuh/api-toolkit/contrib/v4/cacheandgithub.com/aatuh/api-toolkit/contrib/v4/adapters/cacheredisadd supported contrib cache contracts and a Redis-backed cache adapter with TTL, delete, health-check, and reusable adapter-contract coverage. -
github.com/aatuh/api-toolkit/contrib/v4/auditandgithub.com/aatuh/api-toolkit/contrib/v4/adapters/auditpostgresadd supported contrib audit-event contracts, reusable recorder-contract tests, and a transaction-aware Postgres audit recorder that stores actor type, tenant, action, resource, result, request ID, and redaction-checked metadata. The generatedsaas-api-fullaudit migration now includesactor_type. -
github.com/aatuh/api-toolkit/v4/operationsadds additive write-side repository contracts plus lifecycle helpers for validating operation states, terminal states, and pending/running/succeeded/failed/canceled transitions. -
github.com/aatuh/api-toolkit/contrib/v4/asyncadds a supported contrib durable async worker runner with lease/complete/fail store contracts, bounded concurrency, graceful shutdown, low-cardinality metric hooks, and logs that avoid job payloads and raw handler errors. -
github.com/aatuh/api-toolkit/contrib/v4/asyncnow includes an fail-closed handler mux for routing leased jobs by sanitized low-cardinality kind, allowing one durable queue or outbox to back multiple worker concerns without inspecting job payloads. -
github.com/aatuh/api-toolkit/contrib/v4/adapters/operationpostgresadds an supported Postgres-backed operation repository for pollable async operations, including tenant-scoped context helpers, JSON result/problem storage, create/update support, and fail-closed tenant validation. -
github.com/aatuh/api-toolkit/contrib/v4/adapters/outboxpostgresadds an supported Postgres transactional outbox adapter with enqueue, due-event leasing usingFOR UPDATE SKIP LOCKED, lease-owner completion, retry backoff, dead-letter transition, andcontrib/async.Storecompatibility. -
github.com/aatuh/api-toolkit/contrib/v4/objectstoreandgithub.com/aatuh/api-toolkit/contrib/v4/adapters/objectstores3add supported contrib object storage contracts, reusable contract-test helpers, and a raw HTTP S3-compatible adapter with SigV4 request signing, presigned URL hooks, content-type and object-size policy checks, metadata secret-shape rejection, not-found mapping, and a bucket health checker. -
github.com/aatuh/api-toolkit/contrib/v4/webhookdeliveryadds supported contrib outbound webhook delivery contracts with a fail-closed event catalog, tenant-scoped endpoint matching, HMAC-signed HTTP delivery, bounded retry backoff helpers, replay commands, sanitized attempt results, andcontrib/asyncworker integration that keeps endpoint signing secrets out of durable job payloads. -
github.com/aatuh/api-toolkit/contrib/v4/adapters/webhookdeliverypostgresadds a supported Postgres adapter for outbound webhook endpoint lookup, delivery enqueue, outbox job creation, attempt recording, and operator replay. Endpoint signing secrets are loaded through an application-ownedSecretResolverinstead of raw secret storage in the webhook endpoint table; generatedsaas-api-fullmigrations now includeevent_idandlast_status_codeon webhook delivery rows. The adapter also accepts the sharedwebhookdelivery.EndpointPolicyso generated development and integration services can allow localhost HTTP webhook targets without weakening production HTTPS defaults. -
github.com/aatuh/api-toolkit/contrib/v4/middleware/metricsandgithub.com/aatuh/api-toolkit/contrib/v4/middleware/requestlognow expose outbound webhook delivery observation hooks with bounded event type, outcome, and status-class labels that omit tenants, endpoint IDs, delivery IDs, URLs, payloads, secrets, and raw error strings. -
github.com/aatuh/api-toolkit/contrib/v4/middleware/auth/oidcandgithub.com/aatuh/api-toolkit/contrib/v4/integrations/auth/oidcadd supported provider-neutral OIDC/JWKS bearer-token middleware with optional discovery, issuer/audience and algorithm validation, tenant and scope claim mapping, JWKS health checks, env loading, and generatedsaas-api-full--auth oidcwiring. -
github.com/aatuh/api-toolkit/contrib/v4/bootstrap.APIServiceConfignow accepts named shutdown hooks so composed services can close auth, telemetry, or adapter background resources after the HTTP server stops. -
middleware/auth/tenant.Options.RequireAllSourcesnow lets services require every configured tenant source to be present and equal before a handler runs, which supports authenticated-tenant-to-header mismatch checks. -
github.com/aatuh/api-toolkit/contrib/v4/cmd/api-toolkitadds the developer CLI withnew service,contracts lint,contracts diff, andversioncommands. The generatedsaas-apiservice uses chi-backed bootstrap defaults, code-first route contracts, OpenAPI output, public readiness, admin-protected metrics/pprof/detailed health, core API-key and tenant middleware, and idempotent write behavior, plus a checked-in OpenAPI golden workflow. -
Generated
saas-apiservices now fail startup underENV=productionunlessAPI_KEYandADMIN_KEYare explicitly set, so local fallback credentials cannot be deployed accidentally. -
Generated
saas-apiservices now include a.dockerignoreand a hardened multi-stage Dockerfile that runs tests during build, compiles a static binary, and runs it from a non-root distroless runtime image instead ofgo runin a full Go toolchain image. -
Generated
saas-apiservices now include a.gitignorethat excludes local.envfiles, coverage output, temporary directories, test binaries, and the built service binary while keeping.env.exampletracked. -
Generated
saas-apiMakefiles now includecontracts-lintandcontracts-difftargets backed by the api-toolkit CLI, and generatedfinalizeruns those contract checks alongside tests and OpenAPI golden verification. -
Generated
saas-apiMakefiles now makecoverage-checkenforceCOVERAGE_MINinstead of only writing a coverage profile, so generated CI fails closed when test coverage drops below the configured floor. -
Generated
saas-apiMakefiles now installgovulncheckunder.tools/binby default and invoke it through the overridableGOVULNCHECKvariable, so scaffold checks do not require globally mutating the developer Go bin. -
Generated
saas-apiservices now keep memory idempotency storage as the local default but reject it underENV=production; production defaults to the Redis idempotency adapter and requiresREDIS_ADDRbefore startup. -
api-toolkit new servicenow supports--auth jwtand--auth clerkfor thesaas-apiprofile. Generated bearer-token services validate tokens through JWKS, require issuer and audience configuration, extract tenant scope from validated token claims, enforce route scopes, close auth middleware through bootstrap shutdown hooks, and keep generated contract tests and OpenAPI goldens aligned. Development-header and unknown modes still fail closed. -
api-toolkit new servicenow supports the explicitdev-apiprofile with--auth dev-headers. The generated development service requires explicit dangerous-bypass environment settings, separates debug user, tenant, and scope headers, keeps tenant mismatch and idempotent write tests, and refuses to start with dev-header auth whenENV=production. -
Generated services now wire
bootstrap.NewDefaultRouterWithConfigto the contrib Prometheus recorder, so protected/metricsexposes bounded HTTP request counters and histograms instead of only runtime collector output. -
contrib/middleware/auth/clerk.Subjectnow exposes tenant and scope strings derived from validated JWT claims while preserving subject comparability, so applications and generated services can enforce tenant and route-scope policy from Clerk tokens. -
middleware/idempotency.Options.OnOutcomenow emits bounded request-path idempotency outcome events, andOutcomeEvent.MetricLabels()exposes only method, store class, outcome, and status class for metrics. -
github.com/aatuh/api-toolkit/contrib/v4/middleware/metricsnow records boundedidempotency_outcomes_totalPrometheus counters throughIdempotencyOutcomeHook, andgithub.com/aatuh/api-toolkit/contrib/v4/middleware/requestlognow providesIdempotencyOutcomeLogHookwith the same low-cardinality outcome shape. Generatedsaas-apiservices wire both hooks by default. -
middleware/idempotencynow supportsOptions.StorageKeyFuncplusTenantScopedStorageKeyFunc()so multi-tenant services can hash client-supplied idempotency keys with tenant and actor scope before shared storage access. Generatedsaas-apiservices opt into the helper while preserving the originalIdempotency-Keyresponse header on replay. -
github.com/aatuh/api-toolkit/contrib/v4/middleware/metricsnow records boundedhealth_status_changes_totalPrometheus counters throughHealthStatusChangeHook, using onlyfromandtohealth-status labels for scheduler transitions. -
github.com/aatuh/api-toolkit/contrib/v4/middleware/metricsnow treatsnet/http.ServeMuxrequest patterns as route labels when chi route context is unavailable, preserving low-cardinality HTTP metrics for stdlib routers. -
Routes registered through
routecontractsnow attach boundedroutepolicyobservability labels. Contrib metrics records them throughhttp_route_policy_requests_total, and contrib request logging emitspolicy_*fields without raw scopes, tenant sources, rate-limit policy names, or admin policy names. -
github.com/aatuh/api-toolkit/contrib/v4/middleware/metricsnow exposesRoutePolicyLabelsso custom recorders can reuse the same bounded route-policy label normalization as the Prometheus recorder. -
middleware/idempotency.Optionsnow includes additiveRequireKeysupport. Generated SaaS services enable it so unsafe writes withoutIdempotency-Keyfail closed with Problem Details 400 instead of executing untracked. -
Generated service READMEs and security guidance now document that unsafe writes without
Idempotency-Keyfail with Problem Details 400 and that generated idempotency storage keys are tenant and actor scoped. -
Generated services now load bootstrap router env controls for
TRUSTED_PROXIESand rate-limit skip headers, failing startup on malformed proxy CIDRs or unsafe bypass settings. -
Generated services now register a shutdown hook for Redis idempotency clients so production stores are closed through the
bootstrap.APIServicelifecycle. -
Generated services now support
RATE_LIMIT_STORE=redisand default to Redis rate limiting in production, including startup validation and Redis client shutdown hooks. -
Generated scaffold documentation now describes the local memory and production Redis rate-limit store defaults.
-
Generated services now initialize contrib OpenTelemetry tracing from
OTEL_*environment variables, fail startup when tracing is enabled without an OTLP endpoint, and close the tracer provider during service shutdown. -
Generated compose files now include a Redis service, healthcheck, persistent volume, and container-safe Redis address overrides for idempotency and rate limiting.
-
github.com/aatuh/api-toolkit/contrib/v4/telemetry.InitTracingnow returns an error when tracing is explicitly enabled without an OTLP endpoint instead of silently installing a noop exporter. -
api-toolkit versionnow prints Go runtime, main module, core module, contrib module, build commit, and build date metadata for release evidence. -
api-toolkit version --jsonnow emits the same installed tool metadata in a stable machine-readable shape for release evidence and automation. -
Generated services now stamp
/versionfromappVersion,buildCommit, andbuildDate, and the generated Makefile/Dockerfile pass those fields through build flags with localdev/unknowndefaults. -
make v3-readiness-checknow runs focused compatibility-sensitive cleanup guardrails and is included inmake release-checkand release evidence logs, keeping major-version removal planning tied to roadmap, replacement guidance, and release-note requirements. -
CI governance now runs
make v3-readiness-checkexplicitly alongside docs-check and contrib release-note/drift gates. -
api-toolkit new servicenow emits a pinned GitHub Actions workflow that runsmake finalize, keeping generated services on the same test, build, OpenAPI golden, and contract lint path documented by the scaffold. -
The getting-started guide is now scaffold-first and verifies the generated service, OpenAPI golden, and contract lint/diff workflow instead of teaching a hand-written minimal starter as the primary path.
-
Generated service Makefiles now include
fast-check,audit-check,coverage-check,test-race,vuln, andcleantargets so scaffold CI runs race tests and govulncheck in addition to build and contract checks. -
Generated service Makefiles now include optional
sbom-localoutput through Syft, writing SPDX JSON to.ci-result/sbom/sbom.spdx.jsonwithout adding Syft to the default finalize path. -
github.com/aatuh/api-toolkit/contrib/v4/bootstrap.APIServiceConfignow supports namedBackgroundTasksthat run with the service context, fail the service on unexpected task errors, and stop during graceful shutdown. Generatedsaas-apiservices use this to run health refreshes with bounded health-status metrics. -
make release-checknow runscontrib-api-drift-reportas a first-class release-readiness subcheck, and release evidence reuses that log for the structured contrib drift summary instead of leaving supported-adapter API drift only in the evidence-only path. -
api-toolkit contracts diffnow performs compatibility review over parsed OpenAPI operations. Additive operations pass, while removed operations, changed operation IDs, removed documented parameters, added required parameters, removed documented responses, request-body tightening or content removal, response content removal, and changed security requirements fail with deterministic findings. -
api-toolkit contracts diffnow also fails closed when existing operations drift in tenant, idempotency, rate-limit, admin-policy, or deprecation/sunset route policy metadata. -
api-toolkit contracts diffandcontracttest.OpenAPICompatibilityFindingsnow also flag removed or changedcomponents.securitySchemes, so auth header, bearer, OAuth, or OIDC contract drift is caught even when operation-level security requirements keep the same scheme name. -
api-toolkit contracts lint,api-toolkit contracts diff, andcontracttest.OpenAPICompatibilityFindingsnow honor top-level OpenAPIsecurityas inherited operation security and reportglobal_security_changedwhen release-review specs change that default. -
api-toolkit contracts lintnow emits a stableGLOBALsecurity_scheme_undefinedfinding when top-level OpenAPI security references a scheme missing fromcomponents.securitySchemes. -
specs.Registrynow exposesSetSecurityfor code-first top-level OpenAPIsecurity, andcontracttest.SecuritySchemeDefinitionFindingsverifies those global requirements againstcomponents.securitySchemes. -
Generated
api-toolkit new servicescaffolds now usespecs.Registrytop-level OpenAPI security defaults in runtime docs and golden files while keeping protected write operation scopes explicit. -
Generated service READMEs now list admin-protected detailed health and pprof routes, and scaffold tests assert detailed health, metrics, and pprof all require
X-Admin-Key. -
api-toolkit contracts diffnow also reviews OpenAPI component schemas and reports removed schemas, added required properties, removed object properties, type/ref changes, and enum value removals as compatibility findings. -
api-toolkit contracts diffnow applies those conservative schema compatibility checks to inline request and response media schemas on existing operations, so handler-local contract narrowing is caught before release. -
api-toolkit contracts lintnow fails when an operation references a security requirement that is not defined incomponents.securitySchemes, preventing reviewed specs from declaring unenforceable auth. -
contracttestnow exposesSecuritySchemeDefinitionFindingsandAssertSecuritySchemesDefinedso service tests can catch the same undefined OpenAPI security-scheme references as CLI contract linting. -
contracttest.OpenAPICompatibilityFindingsnow reports the same conservative OpenAPI component and inline request/response schema drift findings, so library tests and CLI release review stay aligned. -
github.com/aatuh/api-toolkit/contrib/v4/bootstrapnow exposes middleware stage identifiers, strict/dev middleware order helpers, and startup validation for custom APIService middleware order declarations. -
github.com/aatuh/api-toolkit/contrib/v4/bootstrapnow exposesStrictSaaSAPIMiddlewareOrderfor services that require the full production policy sequence of auth, tenant, and idempotency after the transport middleware stack, and generatedsaas-apiservices declare that order during startup validation. -
github.com/aatuh/api-toolkit/contrib/v4/middleware/metricsnow canonicalizes Prometheus HTTP metric labels so methods stay within standard HTTP verbs plusOTHER/UNKNOWN, invalid statuses collapse to0, and route labels are trimmed before series creation. -
github.com/aatuh/api-toolkit/contrib/v4/middleware/openapiresponse validation now acceptsResponseValidationOptions.ShouldValidateso services can skip response buffering for streaming, upgrade, or large-download routes while keeping request validation enabled. -
middleware/timeout.NewHardnow acceptsOptions.EventHooks, emitting bounded operator metadata for timeout, panic, and response-capture overflow outcomes without exposing panic values, paths, query strings, headers, or bodies. -
github.com/aatuh/api-toolkit/contrib/v4/middleware/metricsnow exposesHardTimeoutEventHookand records bounded hard-timeout outcomes inhttp_hard_timeout_events_total; request logging now exposesHardTimeoutEventLogHookwith the same bounded event shape. -
securityprofile.StreamingRouteOverridenow provides an explicit route-level opt-out for streaming, SSE, websocket, or large-download routes that must avoid hard-timeout response buffering and preserve optional writer interfaces. -
contrib/adapters/idempotencyredis.ReleaseReservationnow performs atomic token-aware compare-and-delete cleanup so stale releasers cannot delete newer in-flight reservations after expiry or replacement. -
middleware/timeout.NewHardnow contains handler panics inside the hard-timeout goroutine. Panics before timeout return deterministic Problem Details responses, while panics after timeout are contained after the 504 response has already won. -
securityprofile.WithHardTimeoutMaxCaptureBytesandRouteOverride.HardTimeoutMaxCaptureBytesexpose hard-timeout response capture limits through global and per-route profile configuration. -
Memory and Redis idempotency adapter legacy recovery events now hash keys by default and expose raw keys only through explicit raw-key opt-in fields for short incident-review windows.
-
The contrib release-note review gate now scopes behavior-change release-note requirements to packages classified as
supported-adapter, preserving supported-adapter governance without over-requiring notes for experimental or wrapper-only contrib internals. -
The contrib release-note review gate now includes package-owned runtime assets such as JSON, YAML, SQL, template, and policy files under supported contrib package directories.
-
docs/supported-adapter-contracts.tsvnow defines behavior contracts and direct-test/release-drift evidence for everysupported-adaptercontrib package. The chi router adapter and zap logger adapter are promoted tosupported-adapterand included in the contrib drift gate. -
github.com/aatuh/api-toolkit/contrib/v4/adapters/ratelimittestadds reusable rate limiter adapter contract coverage, andratelimitredisnow runs it to prove empty-key bypass, per-key isolation, retry-after, and refill behavior. -
github.com/aatuh/api-toolkit/contrib/v4/adapters/healthchecktestadds reusable health checker adapter contract coverage for supported Stripe, Resend, and Clerk readiness checks.
- Added stable core packages
bindingandmiddleware/auth/apikeyfor typed request binding, Problem Details-compatible validation errors, API key authentication, optional auth, context principals, and scope enforcement. endpoints/listnow includes signed HMAC cursor pagination helpers alongside the existing limit/offset APIs.specs.Operationnow supports route contract metadata for parameters, security requirements, scopes, deprecation, sunset metadata, request bodies, responses, and deterministic OpenAPI extensions.contrib/examples/api-keydemonstrates local-only HMAC-backed API key verification and scoped routes.- Added stable core package
httpcachefor ETag and Last-Modified conditional request helpers, including304 Not Modifiedand412 Precondition Failedresponse paths. - Added stable core package
middleware/deprecationfor runtimeDeprecation,Sunset, and deprecation-policyLinkheaders. - Added stable core package
webhooksfor raw-body-preserving HMAC webhook verification, JSON event decoding, accepted-event handling, and Problem Details failures. specsnow supports reusable OpenAPI schemas, responses, security schemes, and schema refs for request and response content.- Added stable core package
routecontractsfor registering handlers and matching OpenAPI operations together. - Added stable core package
negotiationforAcceptandContent-Typenegotiation, including406and415Problem Details responses. specsnow generates deterministic OpenAPI schemas from Go structs for route contract components.httpxnow includes a typed Problem Details catalog for stable machine-readable error codes and catalog-backed error mapping.- Added stable core package
queryparamsfor collection sorting, filtering, sparse fieldsets, and include parameter parsing without storage coupling. - Added stable core package
operationsfor202 Acceptedresponses and pollable asynchronous operation resources. webhooksnow includes outbound HMAC-SHA256 signing helpers for JSON event requests that remain compatible with the existing receiver verifier.- Added stable core package
contracttestfor route contract, OpenAPI, generated contract, and problem catalog assertion helpers. - Added stable core package
routepolicyand opt-inroutecontractspolicy hooks for deriving deprecation headers, content negotiation, auth, idempotency, and rate-limit middleware from route operation metadata. specscan now register reusable Problem Details and validation problem components from anhttpx.ProblemCatalogwhile preserving unchanged OpenAPI output until the catalog helper is used.middleware/ratelimitcan now emit standardRateLimit-Limit,RateLimit-Remaining,RateLimit-Reset, andRetry-Afterheaders when header emission is explicitly enabled.- Added stable core package
idempotentfor idempotency-key requirements, deterministic request hashes, conflict/replay Problem Details, accepted replay responses, and OpenAPI operation extensions. webhooksnow includes replay-window checks, required event-id contracts, timestamp/event-id header constants, and delivery attempt/result contract types without adding retry persistence or provider-specific schemas.- Added stable core package
uploadfor multipart form decoding, required file checks, per-file and aggregate size limits, content-type allowlists, and Problem Details-compatible field errors. - Added stable core package
oauth2for provider-neutral bearer token claims, validators, scope checks, JWKS configuration values, OpenAPI security scheme registration, andauthorization.Actor/scope mapping. - Added stable core package
apitestfor deterministic HTTP API assertions over Problem Details, validation fields, headers, pagination, operation-accepted responses, webhook signatures, and OpenAPI golden output. - Added stable core package
apiclientfor client-side Problem Details decoding, cursor iteration,Retry-Afterparsing, precondition headers, API key transports, webhook signing transports, and JSON request/response helpers.
- Contrib dependencies were upgraded to burn down the imported-only
govulncheckfindings from v39:github.com/jackc/pgx/v5is now onv5.9.0, andgoogle.golang.org/grpcis now onv1.79.3. docs/dependency-risk.mdnow records the v39 advisory ownership map forGO-2026-4762,GO-2026-4771, andGO-2026-4772; the activedocs/vulnerability-dispositions.tsvmanifest is header-only while current imported-only vulnerability evidence is zero.- The release evidence parser contract now includes a mixed same-package contrib
drift fixture where one package has both
Incompatible changes:andCompatible changes:and must summarize as incompatible. - Runtime use of the legacy
response_writerpackage was removed fromhttpx/recoverand maintained contrib HTTP middleware. Those packages now use package-local response wrappers while the publicresponse_writerpackage remains source-compatible for v2 callers. make release-artifact-verify-fixturenow builds a synthetic local release asset bundle and runs the local verifier path. This is only local fixture coverage; publication verification still requires downloaded GitHub draft release assets,RELEASE_ARTIFACT_VERIFY_MODE=publication,RELEASE_TAG,GITHUB_REPOSITORY, real Sigstore material, and online attestation checks.- The release workflow now prints
make release-review-summaryoutput after clean evidence is generated and before release artifact verification steps.
github.com/aatuh/api-toolkit/contrib/v4/middleware/auth/devheadersnow requires explicit dangerous-bypass opt-in and trusted-proxy configuration when enabled, while keeping exported config and middleware values comparable for v2 source compatibility.github.com/aatuh/api-toolkit/contrib/v4/middleware/metricsnow keeps the existingNewPrometheusRecordersignature for v2 source compatibility and addsNewPrometheusRecorderCheckedfor callers that want collector registration conflicts returned as errors.- Idempotency mixed-version compatibility metrics now expose only bounded
method,store_class, andoutcomelabels. Raw paths, idempotency keys, key hashes, and error strings remain available only on structured events for logs or traces. middleware/timeout.NewHardnow enforces a bounded response capture size with a 1 MiB default. Oversized captured responses return Problem Details instead of silently truncating successful responses.- Admin endpoint docs now steer new pprof and detailed-health mounts toward fail-closed registration helpers while preserving legacy source-compatible helpers for v2 callers.
endpoints/health.Handler.RegisterPublicRoutesToandcontrib/bootstrap.MountSystemEndpointsToWithAdminnow give new system endpoint wiring a source-compatible path that keeps public probes separate from admin-only detailed health, metrics, and pprof routes.webhooks.Receivernow returns a generic verifier failure detail by default so custom verifier errors are not echoed to clients. UseReceiverConfig.VerificationErrorDetailonly for explicitly safe text.
- If you treated maintained contrib middleware or adapters as semver-stable,
review
API_BASE_REF=v2.1.0 GOTOOLCHAIN=local make contrib-api-drift-reportbefore upgrading and checkdocs/contrib-api-drift-dispositions.tsvfor the current package-tied disposition. Contrib drift remains report-only; this guidance helps migration review but does not extend the stable v2 API promise to contrib. - For
github.com/aatuh/api-toolkit/contrib/v4/middleware/auth/devheaders, setAllowDangerousDevBypassesandTrustedProxiesexplicitly when enabling debug-header auth.TrustedProxiesis a comma-separated CIDR list. - V3 preparation guidance is now consolidated in
docs/v3-compatibility-roadmap.md: usecompat/billingor app-owned billing ports, database stats snapshots,httpxor package-local response helpers, and token-aware idempotency release before the major-version compatibility removals.
- Release evidence now writes
release-check-summary.jsonschema v2 with per-check command lines, exit codes, durations, log paths, tool versions, and local-vs-GitHub artifact tier metadata. make release-evidencenow runs the release-readiness subchecks through the evidence writer so local summaries have detailed provenance instead of a fixed pass list.docs/package-classification.tsvnow documents API and test quality tiers, and docscheck mechanically validates direct-test, wrapper-smoke, example, generated, tooling, test-support, excluded, and needs-tests classifications.docs/v3-compatibility-roadmap.mdnow contains one removal matrix for provider-shaped billing ports, pgx-shaped database stats,response_writer, tokenless idempotency release, unchecked authz construction, and checked list parser shims.make contrib-api-drift-reportadds a report-only API drift signal for selected high-use contrib adapters and integrations without changing the contrib compatibility policy.make contrib-release-notes-checkadds a lightweight review gate requiring release-note coverage when contrib adapter or integration behavior files change.- Release evidence now records
git_statewith branch/detached state, dirty flag, staged/unstaged/untracked/deleted counts, and the commit checked. - Release evidence now records top-level
publication_eligible; automation must require it to betruealong with passed status, clean provenance, and clean git state before accepting publication evidence. - Release evidence now fails publication mode on dirty worktrees unless
ALLOW_DIRTY_RELEASE_EVIDENCE=1explicitly marks the output as local dirty-tree audit evidence. - Release evidence now archives
.ci-result/release-evidence/logsas.ci-result/release-evidence/release-evidence-logs.tgzand recordspublication_artifact_expectationsfor draft-release asset review. make release-artifact-verifynow verifies downloaded draft release asset names,release-asset-manifest.tsvchecksums, retained release logs, SBOM signatures/certificates, and expected provenance subjects before publishing.- The tag-driven release workflow now verifies keyless SBOM signatures against the GitHub OIDC certificate identity and issuer before uploading draft release assets.
- Release evidence now records
vulnerability_evidencefrom govulncheck logs so imported-but-not-called vulnerability IDs and counts have reviewer disposition indocs/dependency-risk.mdanddocs/vulnerability-dispositions.tsv. - Release evidence now dynamically compares imported-only vulnerability IDs
with
docs/vulnerability-dispositions.tsvand fails when dispositions are missing, incomplete, or expired on the release review date. make release-evidencenow archives report-only contrib drift at.ci-result/release-evidence/logs/contrib-api-drift-report.logand summarizes drift, skipped, compatible, and incompatible counts inrelease-check-summary.json.- Release evidence now records current contrib drift packages and status,
compares them with
docs/contrib-api-drift-dispositions.tsv, and fails when current drift has missing or expired disposition coverage. - Current contrib drift disposition is recorded in
docs/contrib-api-drift-dispositions.tsv, including the incompatible report-onlycontrib/middleware/auth/devheadersdrift. make release-checkandmake release-evidencenow includecontrib-release-notes-check, whilecontrib-api-drift-reportreads selected report-only packages fromdocs/contrib-api-drift-packages.txt.- Incompatible report-only contrib drift is acknowledged for this release:
contrib/middleware/auth/devheaderschanged exported struct comparability because middleware/config types now include non-comparable lifecycle fields. This remains a review signal and does not make contrib stable. make contrib-release-notes-checknow requires incompatible report-only contrib drift acknowledgement to mention the affected package, not only a generic incompatible-contrib phrase.- Docscheck now blocks new production source usage of deprecated billing ports
outside
ports/compat/billingand direct database-stat usage outside compatibility or adapter paths. - Idempotency middleware response capture now uses a package-local helper
instead of importing the legacy
response_writercompatibility package. docs/release-review.mdgives release reviewers a shorter path through the runbook, release notes, stability policy, package classification, compatibility roadmap, and evidence artifacts.- Wrapper and example coverage policy now distinguishes wrapper smoke minimums from build-smoke-only example coverage.
- Package docs for
ports,compat/billing, and the legacy response helper package now identify v2 compatibility-sensitive surfaces and preferred replacements for new code. contrib/middleware/requestlogexpands header redaction defaults for broader authentication/session families and adds payload field redaction helpers for non-header custom fields.contrib/adapters/httpclientretry defaults are now conservative:GETandHEADonly; other methods such asPUTandDELETEnow require explicit opt-in throughRetryableMethods.contrib/bootstrappprof mounting now defaults to opt-in behavior and requires explicit profile intent to enablePprofroutes in production-like defaults.- Idempotency in-flight reservations now carry
ReservationTokenand require tokenized releases for healthy non-legacy records, while legacy tokenless records are recovered during mixed-version rollouts when stale pastInFlightTTL. - Idempotency memory and Redis adapters now expose optional legacy-recovery
telemetry callbacks for tokenless record migrations (
legacy_in_flight_recoveredandlegacy_in_flight_token_mismatch). - Idempotency middleware now emits compatibility telemetry for mixed-version
fallback attempts (
legacy_in_flight_fallback_entered,legacy_in_flight_fallback_recovered,legacy_in_flight_fallback_rejected,legacy_in_flight_fallback_unknown) and validates cross-serviceInFlightTTLalignment viaKnownInFlightTTLs/FailOnInFlightTTLMismatch. ports.ErrLegacyInFlightReservationMissingTokenhas been added for migration-time observability of legacy in-flight record recovery.middleware/auth/authzkeeps the v2-compatible single-return constructor and addsNewRequireRoleMiddlewareCheckedplus bootstrap validation for explicit role requirements and nil resolver detection at route setup.endpoints/listkeeps the v2-compatible single-return parser helpers and adds checked variants (ParseListQueryChecked,DefaultFilterParserChecked,DefaultSortParserChecked) for callers that need field-level validation errors.contrib/middleware/requestlogdocuments and supports deep payload redaction for common typed container shapes (map[string]string,[]map[string]string) while preserving legacy shallow behavior.- Idempotency middleware now emits mixed-version fallback telemetry by default when no
OnLegacyInFlightCompatibilitycallback is configured, defaults legacy compatibility keys to stable SHA-256 redaction, and supports explicit raw-key opt-in throughLegacyInFlightCompatibilityRawKey. - Idempotency startup rollout governance now includes optional strict clock-preflight
checks (
FailOnInFlightClockSkewPreflight) for mixed-version safety, emittingErrLegacyInFlightClockSkewPreflightRiskin strict mode and advisory deprecation-risk warnings in default mode. contrib/adapters/chinow ships a route bootstrap helper that maps chi route registration context into authz role specs and validates role coverage in one startup call, including actionableANY/method route context.contrib/middleware/requestlognormalizes panic observability by always logging recovered panics at error level with failure classification, including committed- response panics and preserving committed status for optional downstream analytics.- Release readiness now has a fail-closed
make release-checkpath that requiresAPI_BASE_REF=v2.1.0, keeps localmake api-checkfallback behavior separate, and publishesrelease-check-summary.jsonwith release SBOM assets. - Root idempotency adapter contract coverage moved to contrib-owned reusable
contract tests so root
go.modno longer carries contrib, Redis, or miniredis requirements for core middleware tests.
-
If your system endpoint wiring relied on implicit pprof exposure in production profiles, use an explicit profile-aware mount helper to re-enable it intentionally.
-
If you require retries for non-idempotent methods, add them explicitly to
RetryableMethodsand confirm the target API contract is idempotent. -
If you are rolling out idempotency migration with shared Redis across mixed binary versions, ensure all services agree on
InFlightTTL. Legacy tokenless in-flight entries will be auto-cleared only when stale, and mixed-version cleanup can be delayed by that TTL when no newer version processes the key first. -
Legacy idempotency cleanup requires aligned timing: set
InFlightTTLconsistently across services and storage layers, including matchingInFlightTTLand key TTL behavior, keepSystemClocksources synchronized, and ensure recordCreatedAtmonotonic assumptions match your deploy latency. Checklist during rollout: (1) runValidateRequireRoleMiddleware-style startup checks for route wiring on all roles-protected endpoints, (2) verifyInFlightTTLparity and shared store key prefixes across all deploy units, (3) monitor middleware telemetry outcomes (legacy_in_flight_fallback_entered,..._recovered,..._rejected,..._unknown) while mixed binaries run, and (4) remove tokenless-compatibility behavior only after mixed-version fallback suppression reaches zero. -
Recommended rollout telemetry contract:
- Labels:
method,path,store_type,outcome,key(optional), anderror. - For metric collectors, prefer
LegacyInFlightCompatibilityMetricSinkandLegacyInFlightCompatibilitySampleEveryduring large rollout waves. - Use
LegacyInFlightCompatibilityAsyncwhen callback latency must not affect request latency. KeepLogger/compatibility sink diagnostics during initial rollout windows for deterministic evidence. - Default warning thresholds:
legacy_in_flight_fallback_unknown > 0for 5 minutes indicates release risk and should page.legacy_in_flight_fallback_rejected / legacy_in_flight_fallback_enteredabove0.5%over 10 minutes indicates high key-level contention and should be investigated.legacy_in_flight_fallback_recovered / fallback_entereddropping below99%indicates likely TTL/clock contract mismatch.
- Dashboard query examples:
sum by (store_type) (rate(legacy_in_flight_fallback_unknown[5m])) > 0 sum by (store_type) ( rate(legacy_in_flight_fallback_rejected[10m]) ) / sum by (store_type) (rate(legacy_in_flight_fallback_entered[10m])) > 0.005 sum by (store_type) ( rate(legacy_in_flight_fallback_recovered[10m]) ) / sum by (store_type) (rate(legacy_in_flight_fallback_entered[10m])) < 0.99 - Labels:
-
Backpressure behavior:
- Synchronous sinks execute in the request path; if a custom sink is slow or blocking, requests can back up at startup and during mixed-version load.
- Enable async emission for high-volume migrations and confirm callback exceptions are tracked by tests or sink-specific observability, since they are intentionally recovered and must not abort request handling.
-
If you rely on zero-config retry behavior in
contrib/adapters/httpclient, review all non-GET/HEAD consumers and update to explicitRetryableMethodsonly for confirmed replay-safe routes and clients. -
NewRequireRoleMiddlewarekeeps the v2-compatible single-return constructor. Invalid wiring is still fail-closed at runtime until fixed and will return401(no actor) or403(actor without role) as applicable. For startup validation, useNewRequireRoleMiddlewareCheckedor runValidateRequireRoleMiddleware(method, route, mw)for each protected route.authzMw, err := authz.NewRequireRoleMiddlewareChecked("admin", func(ctx context.Context) []string { if actor, ok := authorization.ActorFromContext(ctx); ok { return actor.Roles } return nil }) if err != nil { panic(err) } if err := authz.ValidateRequireRoleMiddleware(http.MethodGet, "/admin", authzMw); err != nil { return fmt.Errorf("route contract check failed: %w", err) }
-
If you need startup authz migration validation, prefer registry-level validation via
ValidateRequireRoleMiddlewareRoutesduring bootstrap and fail startup on the first startup pass when any route fails this check.checks := []authz.RequireRoleRouteSpec{ {Method: http.MethodGet, Route: "/admin", Middleware: adminMw}, {Method: http.MethodPost, Route: "/billing", Middleware: billingMw}, } if err := authz.ValidateRequireRoleMiddlewareRoutes(checks); err != nil { return fmt.Errorf("route contract scan failed: %w", err) }
-
Rollout symptoms of misconfigured authz route wiring are usually a startup failure in CI or process init (
invalid role middleware for route ...), then runtime401for unauthenticated requests and403for missing-role users. Rollback sequence when migration checks block startup: (1) restore previous middleware wiring, (2) temporarily disable strict constructor checks only as a temporary guardrail, (3) reapply the startup check after role/route registration is repaired, and (4) rerun staged rollout. -
requestlogpayload redaction assumes redaction-sensitive names based on canonical field patterns (token,secret,password, common aliases) before any deep traversal. For typed payloads, normalize unsupported custom shapes to map/slice-of-map shapes before callingrequestlog.RedactPayloadFieldsDeep(seecontrib/middleware/requestlog/doc.go). -
For mixed-version idempotency rollouts, run startup with
FailOnInFlightTTLMismatchandFailOnInFlightClockSkewPreflightonly after you have parity checks and rollback strategy in place. Keep both off during the first boot of a migration wave if you need warning-only discovery. -
ports.IdempotencyReleaser.Release(ctx, key)remains the v2 compatibility contract for existing custom stores. New stores should also implementports.IdempotencyReservationReleaser.ReleaseReservation(ctx, key, token)so middleware can release only the current tokened in-flight reservation. -
To upgrade authz checks with chi, either build explicit
[]authz.RequireRoleRouteSpecand validate viaauthz.ValidateRequireRoleMiddlewareRoutesor usechi.ValidateRequireRoleMiddlewareRouteswith a route+method resolver closure to map protected handlers.
contrib/telemetry.WrapHTTPClient(nil)now creates an instrumented client with a 10 second timeout instead of an unbounded zero-timeout client.contrib/migrator.Options.LockTimeoutcan now override the advisory lock wait timeout; zero keeps the previous 10 minute default.contrib/migrator.Options.UnlockFailureHandlerand the existing migrator logger can now surface advisory unlock failures without replacing the primary migration result.
- If you intentionally need no client-level timeout for a telemetry-wrapped
net/httpclient, pass an explicit&http.Client{}toWrapHTTPClient; prefer request contexts with deadlines for long-running calls.
- Billing contracts in
ports/billing.goare now formally deprecated for new code. The same Stripe-shaped v2 model is available through the new compatibility packagegithub.com/aatuh/api-toolkit/v4/compat/billing. contrib/adapters/pgxpool.Adapter.StatSnapshot()now copies plain-value pool stats directly from pgxpool instead of routing through the legacyDatabaseStatswrapper path.
- Existing code that imports billing contracts from
portskeeps working for the rest of v2, but new code should migrate togithub.com/aatuh/api-toolkit/v4/compat/billingso the provider-shaped dependency is explicit before v3 extraction. - If your health or observability code still reads
DatabasePool.Stat()or depends onDatabaseStats, move it toDatabasePoolSnapshotProvider,SnapshotDatabasePoolStats, or adapterStatSnapshot()methods. The legacy counter interface remains for compatibility adapters, not as the preferred generic path.
contrib/middleware/auth/devheadersnow requires explicit dangerous-bypass opt-in and trusted-proxy configuration before it will honor debug auth headers.- Health endpoints now fail closed on empty or miswired liveness/readiness probe sets, and HTTP handlers only expose detailed dependency output when
ports.HealthCheckConfig.EnableDetailedis explicitly enabled. contrib/adapters/txpostgres.WithinTxnow attempts deferred rollback with a bounded cleanup context even when the caller context is already canceled or timed out.contrib/adapters/txpostgresnow fails closed withErrPoolNotConfiguredwhen callers forget to wire a database pool, instead of panicking on nil-pool use.endpoints/docs.New()andNewDefaultHandler()now default to the first-party static docs surface; callers must opt into the CDN-backed Swagger UI mode withdocs.NewSwaggerUI()orDocsConfig.HTMLMode.contrib/migratornow records commit-acknowledgement failures asuncertainand blocks later runs when a prior migration record is stillstartedoruncertain.scheduler.Runnernow persists final run records through a bounded cleanup context so graceful shutdown does not dropLastFinishedupdates for jobs that already completed.scheduler.Runnernow surfaces recorder persistence failures through structured logs and optionalSetRecorderFailureHandlercallbacks without changing the completed job result or schedule cadence.- JWT and Clerk middleware now share internal auth/JWKS validation primitives with no intended public API or configuration change.
- If you previously enabled
devheaderswithout explicitly opting into dangerous bypasses or without trusted-proxy configuration, startup will now fail fast until you set both intentionally. - If you had tests or thin wiring paths that called
txpostgres.New(nil)ortxpostgres.FromCtx(..., nil), they now returnErrPoolNotConfiguredinstead of panicking. - If you relied on
docs.New()orNewDefaultHandler()to serve Swagger UI with CDN assets, switch todocs.NewSwaggerUI()or setDocsConfig.HTMLMode = ports.DocsHTMLModeSwaggerUIexplicitly. - If a deployment previously canceled scheduler job contexts during graceful shutdown, completed jobs now get a short recorder-persistence window before exit so restart-time suppression remains accurate.
- If operators previously relied on
/healthor equivalent routes exposing dependency-level detail by default, setEnableDetailedexplicitly during wiring; otherwise only basic probes should remain visible. - If your deployment workflow retried migrations automatically after commit errors, stop doing that. Inspect the database state and reconcile
schema_migrationsbefore rerunning when a migration is recorded asstartedoruncertain. - If you need alerting when scheduler run history cannot be persisted, wire
SetRecorderFailureHandleror monitor the new recorder-failure log events; job completion alone no longer implies recorder persistence succeeded. - JWT and Clerk integrations should be behaviorally equivalent to their prior public APIs, but custom wrappers that depended on edge-case differences in bearer parsing, claim requirements, or skip-header handling should be revalidated.
- Idempotency middleware now releases failed reservations after downstream
5xxresponses and panics, so retries with the same payload andIdempotency-Keyare not blocked behind a stale in-flight record. - Idempotency middleware now fails closed with
503 Service Unavailablewhen it cannot persist a completed replay record, and it stores an ambiguous state for that key instead of reopening it for another execution. - Idempotency middleware now includes authenticated actor and tenant scope in the default request hash, preventing cross-principal or cross-tenant replays from reusing the same key and payload.
- Idempotency middleware now caps buffered replay bodies at
1 MiBby default and returns503 Service Unavailableplus an ambiguous key state when a handled response exceeds the replay buffer limit. scheduler.Runnernow recovers scheduled-job panics, logs and records them as failed runs, and keeps future intervals alive instead of letting one bad job crash the process.scheduler.Runnernow prevents the same job name from overlapping with itself across duplicateStartcalls or duplicate scheduling of the same job.bootstrap.ProfileStrictAPIno longer enables wildcard CORS by default; browser-facing cross-origin access now requires an explicitWithCORSOptions(...)allowlist.contrib/config.LoadFromEnvnow treats invalid present bool and int values as startup errors instead of silently falling back to defaults.- Docs endpoints now return
404when the HTML docs surface is disabled or when no authoritative OpenAPI document is available. DocsConfig.EnableJSONandDocsConfig.EnableYAMLnow control which discovered OpenAPI formats may be served on the configured docs path.- Multi-source migrator loading now documents its actual contract: duplicate version+direction pairs are rejected.
- The pagination example now returns one field-level validation shape for invalid
limitinputs even whenquerylimitsrejects the request before the handler.
- If clients previously saw
409 Conflictafter a failed idempotent write, retry behavior has changed: the same payload andIdempotency-Keycan now be retried immediately after downstream5xxand panic paths, but not after completed-response persistence failures or replay-buffer overflows. - If clients previously received the original success response even though completion persistence failed, they now receive
503 Service Unavailableand the key remains blocked in an ambiguous state until it expires or is reconciled. - If authenticated middleware previously ran after idempotency, default caller scoping will not apply. Move auth and tenant middleware earlier in the stack to keep replay protection scoped per caller.
- If a route can stream, hijack, upgrade, or return large bodies, exclude it with
ShouldHandleor raiseMaxResponseBytes; otherwise oversized handled responses now fail closed with503 Service Unavailableand block same-key retries for the key lifetime. - If a scheduled job panic previously terminated the process, that failure is now contained and surfaced through scheduler logging and run recording instead.
- If application code called
scheduler.Runner.Startmore than once or reused the same job name across duplicate schedules, those executions no longer overlap. Validate any workload that previously relied on concurrent execution of the same named job. - If browser clients previously relied on
ProfileStrictAPIto emitAccess-Control-Allow-Origin: *, they must now set an explicit allowlist withWithCORSOptions(...)during bootstrap. - If deployment environments previously contained malformed bool or int values such as
MIGRATE_ON_START=maybe, startup now fails fast instead of silently using defaults. Validate env files and secrets before rollout. - If deployment environments used undocumented semantic values such as
ENV=qa,ENV=prod,LOG_LEVEL=verbose, orLOG_LEVEL=warning, startup now fails fast. Usedevelopment|staging|productionforENVanddebug|info|warn|errorforLOG_LEVEL. - Docs handlers no longer return a synthetic OpenAPI document when no authoritative spec exists. Expect
404for disabled docs surfaces and for missing OpenAPI files unless a real document is configured. DocsConfig.EnableJSONandDocsConfig.EnableYAMLnow control which discovered OpenAPI formats can be served. Verify custom docs paths and any YAML-based docs setup during upgrade.