2026 Q3
Q3 2026 — go-openapi Organization Summary
Period: May 30, 2026 — August 31, 2026 Overall effort: 1,677 commits across 23 repositories — 1,169 of them from people (the rest are automated maintenance from bots)
Q2 ended with the expectation that most libraries would reach v1.0 and clear the way for a v2. Both happened.
jsonpointer, jsonreference and inflect cut their first v1.0.0; spec, analysis and validate were frozen; and three new
repositories — core, go-yaml and codegen — opened to hold what v2 will be built from. Alongside
them, codescan finished the rewrite it started last quarter and then spent most of the summer working
through go-swagger’s oldest generate spec bugs.
1. The v2 foundations: three new repositories
core
core (v0.0.1 → v0.0.3, first tagged July 27) holds the low-level machinery the v2 libraries will sit on:
json for parsing and dumping JSON and YAML as compact immutable documents, with jsonschema and oai to
follow. It is explicitly not a replacement for encoding/json — it does not marshal Go structs. It keeps a
JSON document dynamic, deferring the resolution of individual values to Go types. Schema analysis and spec handling both
need that deferral.
What landed: a fast JSON lexer for buffers and streams, a separate YAML lexer, writers, a store that packs JSON
values into a compact memory area, and an expressions package. The lexers carry assembly generated with
avo (json/internal/utf8x/_asm, json/lexers/default-lexer/internal/strscan/_asm). Correctness work ran
alongside: UTF-8 validation on string values and on the way out, rejecting UTF-32 input with the not-UTF-8
error, stripping a leading UTF-8 BOM, and stopping a self-referential merge key from recursing forever.
The YAML lexer is measured against the YAML Test Suite. It is not currently super efficient: it wraps
github.com/goccy/go-yaml v1.19.2, and we’ll move that dependency to our newgo-yamlfork.The two stay distinct.
core’s yaml-lexer produces JSON-compatible documents — OpenAPI specs, JSON schemas.go-yamlcovers the wider range of YAML use cases: encoding and decoding, AST transforms.
The repository is marked experimental — v0.0.x releases may break the API.
go-openapi/core is going to be the center of our attention during Q4, to support our new document model for schemas and specs.
go-yaml
go-yaml is a fork of goccy/go-yaml, and after this quarter it is a
hard fork. go-openapi needs three things from a YAML library that none offers together: a token and AST
surface with accurate positions (the editor, TUI and diagnostic tooling needs to know where every construct
is), a bounded memory footprint on large documents, and conformance good enough to project YAML onto JSON
semantics faithfully.
At the fork point the whole input was materialized as []rune, every token was retained, and nothing could be
emitted before the entire document had been parsed — an AST cost roughly 32× the source. This quarter:
- The
[]runeis gone. A parse now makes 84% fewer allocations. The scanner indexes the source by byte, slices a plain scalar’s text from the source instead of copying it, and hands out tokens, positions and grouping scaffolding in blocks. The AST gained an arena. - A token now carries its position rather than pointing at one, and drops
IndentLevel, the recorded indicator and character type (both derived from the token type instead), and the token chain an error used to walk. parser2reads its tokens from an iterator, and its grouping passes — directives, explicit keys, map keys, anchors, aliases, tags, block scalars, line comments — were converted to read from a stream one at a time. Streaming is the remaining work.- Conformance against the YAML Test Suite moved from 88.3% to 100% of scored cases.
- The root API went from 133 exported entries to four functions; the rest moved to
codec,ast,parser,errorsandexpressions.
For now, licensing is unchanged: the repository stays under goccy/go-yaml’s MIT license and claims no separate
copyright. This is still WIP and there is no release yet.
codegen
codegen (v0.0.1, August 24) lifts go-swagger’s code-generation machinery into its own module: a new name
mangler that supersedes swag/mangling, a genapp harness that renders, formats and writes out a generated Go
tree, and a formatter that replaces goimports and needs no Go toolchain — it resolves package names via
go list, prunes only the imports whose package name it knows, sorts and dedups the whole import block, and
simplifies redundant aliases. WithRoot confines written files to a directory. The Go funcmap was split by
topic, dropping sprig.
A new templates repository. go-swagger’s own (generator/internal/templates-repo) is mutable: it is
filled by repeated LoadDefaults, LoadDir, LoadContrib and AddFile calls behind a sync.Mutex, and
overriding a template depends on two flags set after construction, SetAllowOverride and
SetProtectedTemplates. codegen replaces it with a value built in one pass. New takes its sources as
options — FromFS, FromDir, FromTemplate, FromRepository — parses every asset together so any template
can call any other, then freezes the set. Overriding needs no flag: sources are read in the order they are
declared and the last declaration of a name wins. Clone re-parses from scratch, so a template that calls an
overridden one picks up the new definition, and the two repositories share no state — one generation run
cannot disturb another. Rebase, Merge and Coalesce derive repositories from repositories, and
FromRepository mounts a set at a chosen point, so two independently written sets assemble without their
macros colliding. WithRoots prunes the set to the templates a run uses, and Repository.Audit reports
every name that more than one asset declared, with the definition that stands and the ones it replaced.
conformance-suites was also created (August 7) to hold conformance test suites and tools for JSON, YAML and OAI documents. A by-product of our work on JSON and YAML parsers is the production of grammar-based generated validation corpora. During Q4, we’ll share this work as a set of released conformance test suites, which cover their grammar more extensively than their official counterparts.
2. codescan: the grammar rewrite landed, then the backlog
Short story
Since the carve-out from go-swagger, the codescan library has been subject to a heavy rewrite.
In May, the library was refactored to disentangle the spec generation into layered packages. The next move was to give up the regexp-based logic and replace it with a more capable lexer and parser with a proper grammar. The last move was to replace the package loading logic and remove the go toolchain dependency.
We did not forget documentation: the library comes with its own doc site loaded with examples, tutorials and reference material.
Two standalone CLI tools and an online playground (WASI-powered) let you use the library without waiting for a go-swagger release.
Q2 reported a rewrite in progress to retire the 60–70 regular expressions behind codescan’s annotation
parsing, with only a fraction merged. It landed on June 2: a preprocessor turning comment groups into
positioned lines, a lexer, a recursive-descent parser with a typed Block family, a Walker visitor with a
diagnostic surface, YAML and swagger:route body sub-parsers, a grammar-based schema builder, and a grammar
seam in the scanner. The doc site publishes railroad diagrams for the EBNF grammar. By August the parsers
read an annotation line instead of matching it.
Then the backlog. With a grammar to reason about, the quarter turned to go-swagger’s generate spec
issues — 232 distinct issues referenced, the oldest being go-swagger#91, and 73 test(bugs) commits
locking behavior with regression fixtures. Fixes included markdown bullet lists (*, +) identified like
YAML dash lists (go-swagger#1726), block-comment framing stripped from path annotations (go-swagger#1595),
Kubernetes marker comments dropped from descriptions (go-swagger#2687), Security: parsed as real YAML so
AND grouping works (go-swagger#2294), inline-regex path params reduced to RFC 6570 Level-1
(go-swagger#2909), and x-deprecated marking for deprecated models and fields, including godoc’s
Deprecated: (go-swagger#3138).
New tooling. genspec-tui, an interactive TUI that live-renders a spec from its source (July 31), grew
severity-colored diagnostic rows, movable pane dividers, a guarded F5 reload, annotation lookup without
leaving the file, a validation tab with exact finding locations, and a scan profile naming where the time and
memory went. genspec followed as a standalone command-line generator, and package cliconf gave every command a
configuration file read before the flags, with -c and -no-config to pin or refuse it. genspec-wasi is a
headless generator needing no toolchain, and the playground now scans Go source in the browser, inside a
documentation page.
Performance. The scanner can load and type-check packages without a Go toolchain, take dependency types from compiled export data or the build cache, and — since August 17 — read dependencies from source again by default. Releases v0.34.1 → v0.36.4.
3. Security hardening across the spec toolchain
Several vulnerability reports converged around an overlooked attack vector: loading remote untrusted specs, which could, if maliciously crafted, produce potentially harmful code or disrupt a toolchain based on go-openapi libraries.
Vulnerability reports have been published to github. However, we did not reclaim CVEs for these, as github systems are already overcrowded by the frenzy of agent-generated vulnerability reports across the board.
Fixes landed in two passes, in June and July.
June. swag sandboxes local file loading behind WithRoot (GHSA-v2xp-g8xf-22pf) and documents the
loader’s security implications; loads added secure loaders and containment options; go-swagger
hardened generated code against untrusted-spec injection.
July. spec caps $ref expansion node count against amplification DoS, stops making a network request
in IsValidURI, accepts an option-aware document loader, and warns that the default $ref loader is not
sandboxed. swag bounds recursion depth in its YAML↔JSON and ordered-JSON transforms and detects YAML
anchor/alias expansion cycles. go-swagger escapes untrusted spec, header, flag, format, enum, default and
content-type values in generated code — and, in August, in generated struct tags — and added codegen options
to restrict $ref resolution. The confined loader was wired down through loads, validate and
analysis.
Seven security advisories were responsibly reported over the quarter (see the contributors section). We’ve run various independent scanners and landed security or potential vulnerability fixes against ci-workflows, gh-actions, go-yaml and go-swagger. Template injection in the GitHub workflows took two passes in ci-workflows (#254, #255) and in gh-actions (#125, #127), and one in go-swagger (#3457).
4. The v1.0.0 line opens, and three libraries freeze
jsonpointer, jsonreference and inflect each cut v1.0.0 in July — the three oldest,
lowest-churn modules, and stable for years before the tag. jsonreference followed with v1.0.1 in August,
fixing $ref canonicalization. spec cut its own v1.0.0 on September 1, just after this window closes.
spec, analysis and validate got a last correctness pass and were then frozen: deterministic,
reproducible schema expansion over sorted map walks; $ref and URL normalization aligned with
jsonreference; validate no longer rewriting the caller’s document; a gob round-trip that no longer drops
zero-valued fields; analysis flattening $refs under unmapped keywords and exposing where each $ref is
declared. The three have reached the limits of their exposed data model. They stay maintained, but their APIs
are closed and the remaining known issues move to v2. The fixes were onboarded into go-swagger the same week.
5. runtime, strfmt and swag
runtime (v0.32.3 → v0.33.1) gained lazy multipart-form streaming as a primitive, contributed by
@fpawel and surfaced through go-swagger’s generated servers and a new examples
playground; middleware now sets http.Request.Pattern to the matched route, contributed by
@delthas.
strfmt (v0.26.3 → v0.27.0) added ISO-4217 currency and ISO-3166 country formats and an ISO 8601 /
RFC 3339 duration-iso8601 format, fixed RFC 4648 base64 handling, validated the uri format for absolute
URIs carrying a fragment, and started fuzzing its formats.
swag (v0.26.1 → v0.29.1) deprecated its jsonname module in favor of jsonpointer’s provider, added a
generic sync.Pool factory and AppendXXX number formatting, refactored its JSON-adapter pools and options,
and fixed rooted and absolute in-root path handling on Windows. jsonpointer (v0.23.2 → v1.0.0) was split
into specialized sub-package modules and dropped mailru/easyjson as a default dependency.
What’s next?
Unlike spec, validate, analysis, which are now frozen and will only receive critical and security fixes, repos runtime, swag and strfmt will continue to evolve with a “v2” tag. We’ll publish their respective roadmaps during Q4.
6. go-swagger
Eleven releases, v0.34.1 → v0.36.5. The toolkit tracked codescan release by release for generate spec,
and onboarded the spec/analysis/validate freeze fixes in August.
Generator work: explicit casing preserved for x-go-name (#3319, #3357), an initialisms regression from
v0.34.0 fixed, --with-stringer for model String() methods, --with-go-run to invoke swagger via go run
in a //go:generate line, --no-default-omit-empty, --generate-getters for optional getters on all fields,
const blocks for array-item enum values, discriminator allOf models, nil-pointer unmarshal targets for
nullable additionalProperties and tuple items, and a CLI that advertises only the options each command
actually uses. Windows ARM64 binary releases were reinstated. Producers and consumers are now stable across
generations.
The examples repository gained a spec-first documentation site at https://goswagger.io/examples/, with guides, tutorials and a streaming multipart file-server playground, regenerated from go-swagger master by CI.
What’s next?
go-swagger’s codegen machinery is now close to being fully outsourced (to go-openapi/codegen).
Q4 releases will progressively offer options to adopt the v2 features as they become available.
7. testify
v2.6.0 (June) added the go1.26 ErrorAsType / NotErrorAsType assertions with go-version-guarded
codegen, and guarded the reflection walkers against nil interface values and cyclic inputs. v2.6.1
(August) was a correctness release: recursion caps at 1000 across Empty, FileEmpty, ErrorIs,
ExportedValues and spew’s isTime, a panic guard in Implements, and fixes to the messages reported by
IsDecreasing, InDeltaSlice and SeqNotContains.
v2.7.0 (August 23) exposed generic assertions as
forward methods on go1.27, build-guarded so earlier toolchains are unaffected, and added ErrorNotContains,
mixed-sign EqualValues, rune and byte matching in Contains, and quoted string values in Empty failures.
The v1 compatibility line was kept alive with v1.12.0 and v1.12.1.
What’s next?
testify/v2 is feature complete and the pace of releases (one minor a month) has now slowed down to one minor per quarter.
We continue to closely track the upstream repo and land new features or fixes requested upstream.
The next endeavor for testify/v2 is to revive test suites, which we dropped with the fork (tentatively scheduled for EOY).
8. CI/CD, dependencies and documentation
ci-workflows moved v0.3.1 → v0.6.1 across seventeen releases. It added the shared
webhook-announcements workflow that posts to Discord, a shared change-detection workflow replacing
tj-actions/changed-files (adopted by go-swagger), options on the go-test workflow, coverage and
secret-handling hardening, and fixes to the mono-repo release flow. gh-actions went v1.4.15 → v1.4.18.
doc-site (this repository) shipped the daily repository status dashboard — status, activity, quality and GitHub tabs over every go-openapi and go-swagger repo, collected at 06:00 UTC — with commits-since-release counts linking to the GitHub compare view, and go-yaml added in August. Monthly reports are now generated and announced automatically; the contributors workflow moved from weekly to monthly.
Impact Assessment
| Area | Assessment |
|---|---|
| Big movers | codescan and go-yaml were the two most active repositories. codescan finished its grammar rewrite and then worked through the historical generate spec backlog; go-yaml went from soft fork to hard fork while its parser was rebuilt around streaming. |
| Direction | core, go-yaml, codegen and conformance-suites were all created this quarter, and all four are v2 components. |
| Stability | jsonpointer, jsonreference and inflect reached v1.0.0; spec followed on Sept 1. spec, analysis and validate are frozen, with known issues deferred to v2. |
| Security | Two hardening passes over the spec toolchain: sandboxed loading in swag and loads, $ref expansion caps in spec, escaping of untrusted values in go-swagger’s generated code. Seven advisories reported by outside researchers. |
| Downstream (go-swagger) | Eleven releases. The generator tracked codescan release by release and onboarded the library freeze fixes. New CLI flags and a run of generator fixes, several from outside contributors. |
| Test Framework | testify held its cadence — v2.6.0, v2.6.1, v2.7.0 — and kept the v1 line patched. |
| Risk Level | Medium. The v1 libraries are frozen or at v1.0.0 and low-risk. The new repositories are explicitly experimental: core is v0.0.x with a moving API, go-yaml has no release, codegen is v0.0.1. |
Repository Highlights
| Repo | Tag | Status |
|---|---|---|
| analysis | v0.26.2 | Confined document loader; flatten $refs under unmapped keywords; expose where each $ref is declared — now frozen |
| ci-workflows | v0.6.1 | Shared webhook-announcements and change-detection workflows; coverage and secret hardening; mono-repo release fixes |
| codegen | v0.0.1 | New repo: name mangler superseding swag/mangling, genapp generation harness, toolchain-free Go formatter, immutable templates repository (concurrent-safe, override by declaration order) |
| codescan | v0.36.4 | Grammar rewrite landed; 232 historical generate spec issues swept; genspec, genspec-tui, WASI browser playground; toolchain-free package loading |
| conformance-suites | — | New repo: conformance suites and tools for JSON, YAML and OAI documents |
| core | v0.0.3 | New repo: JSON and YAML lexers, writers and a compact document store, with avo-generated assembly; measured against the YAML Test Suite |
| doc-site | — | Daily repository status dashboard; automated monthly reports and Discord announcements |
| errors | v0.22.8 | Dependency updates |
| gh-actions | v1.4.18 | Action refinements; aikido-autofix security fixes |
| go-yaml | — | New hard fork of goccy/go-yaml: root API 133 entries → 4, conformance 88.3% → 100%, 84% fewer allocations, streaming parser in progress |
| inflect | v1.0.0 | First v1.0.0 |
| jsonpointer | v1.0.0 | First v1.0.0; split into sub-package modules; mailru/easyjson no longer a default dependency |
| jsonreference | v1.0.1 | First v1.0.0; $ref canonicalization fixes |
| loads | v0.25.2 | Secure loaders and containment options; loader chaining and builder-with-options |
| runtime | v0.33.1 | Lazy multipart-form streaming; middleware sets http.Request.Pattern |
| spec | v0.22.11 | $ref expansion DoS caps; no network call in IsValidURI; confined loaders; deterministic expansion — now frozen (v1.0.0 followed on Sept 1) |
| strfmt | v0.27.0 | ISO-4217 currency, ISO-3166 country and ISO 8601 duration formats; RFC 4648 base64 fix; format fuzzing |
| swag | v0.29.1 | Sandboxed local loading via WithRoot (GHSA-v2xp-g8xf-22pf); bounded recursion in YAML↔JSON transforms; jsonname deprecated |
| testify | v2.7.0 | go1.26 ErrorAsType; go1.27 generic forward methods; recursion guards; v1 line kept at v1.12.1 |
| validate | v0.26.5 | Injectable document loader; no in-place mutation of the caller’s document — now frozen |
| go-swagger | v0.36.5 | Eleven releases; tracks codescan for generate spec; new CLI flags; untrusted values escaped in generated code |
| go-swagger/examples | — | Spec-first documentation site at goswagger.io/examples; streaming multipart file-server playground |
Summary
Q3 2026 started go-openapi/v2 and closed off the v1 line. Three new repositories opened:
core, holding JSON and YAML lexers, writers and a compact document store; go-yaml, a hard fork of
goccy/go-yaml rebuilt around streaming and accurate positions; and codegen, which lifts go-swagger’s
generation machinery — name mangling, a generation harness, a toolchain-free formatter and an immutable
templates repository that two generation runs can share — into a module of its own. A fourth, conformance-suites, holds the test corpora the first two are measured against.
The v1 libraries were closed off at the same time. jsonpointer, jsonreference and inflect cut
their first v1.0.0, and spec followed on September 1. spec, analysis and validate took a
final correctness pass — deterministic expansion, $ref normalization, no in-place mutation of the caller’s
document — and were then frozen, their remaining known issues moved to v2.
codescan did the quarter’s heaviest work. The rewrite Q2 left in progress landed on June 2: the 60–70
regular expressions are gone, replaced by a preprocessor, a lexer, a recursive-descent parser and a
diagnostic-carrying walker. With that in place the repository worked through go-swagger’s oldest
generate spec bugs — 232 issues referenced, 73 of them pinned by regression tests — and shipped new tooling
around the scanner: a genspec CLI, an interactive TUI, and a WASI build that scans Go source in the browser.
Security ran through the whole period. swag sandboxes local file loading behind WithRoot
(GHSA-v2xp-g8xf-22pf), spec caps $ref expansion against amplification DoS and no longer makes a network
call in IsValidURI, and go-swagger escapes untrusted values throughout its generated code. Seven advisories
were reported from outside the project.
Downstream, go-swagger shipped eleven releases and tracked codescan release by release. testify kept its cadence with v2.6.0, v2.6.1 and v2.7.0 while patching the v1 line, and the shared CI platform continued to absorb per-repository workflow logic.
Thanks to Our Contributors
A warm thank-you to the community members who landed changes in go-openapi and go-swagger this quarter. Whatever its size, every contribution helps keep the project healthy — we’re grateful for your time and care:
- @fpawel — runtime, go-swagger, examples
- @RubenPari — go-swagger
- @KT-Doan — codescan
- @delthas — runtime
- @alexandear — jsonpointer
- @HNO3Miracle — validate
- @patchwright — strfmt
- @pyrohedgehog — go-swagger
- @bobcallaway — go-swagger
- @014-code — go-swagger
- @sanmaxdev — go-swagger
- @uddeshsingh — go-swagger
- @youdie006 — go-swagger
- @dashitongzhi — go-swagger
Thanks also to @bernot-dev for the idea and parser behind strfmt’s ISO 8601 duration format, and to @hsdfat for a fast-turnaround enum fix in codescan — contributions that shaped the work even where the patch itself could not be merged as-is.
Security advisories this quarter were responsibly reported by @KrisKennawayDD, @RamiAltai, @weiz-cn, @Gal3m, @EladMeged-Novee, @sondt99 and @abhayclasher — thank you.
Thank you all. 🙏