Two pieces of non-managed surface have drifted away from src/Glyph11. Filing them together because they are the same shape: code outside the managed parser that nothing forces to keep up.
1. Drop the Kotlin bindings
bindings/kotlin/ is a Panama FFM binding over libglyph11 - two Kotlin files (Glyph11.kt, Main.kt) plus a full Gradle toolchain (gradlew, gradlew.bat, gradle/wrapper/, build.gradle.kts, settings.gradle.kts).
Why it should go:
- Nothing builds it. No workflow in
.github/workflows/ references gradle or kotlin - build.yml, core-tests.yml, sonar.yml, package-native.yml, package-pico.yml and release.yml are all .NET or C. There is no automated proof it still compiles.
- It has already fallen behind. Last touched 2026-07-10; the managed parser has moved since.
- It is not part of what the project ships. The README advertises three packages -
Glyph11, Glyph11.Native, Glyph11.Pico - and Kotlin is none of them.
- It inherits every C-core gap below, so keeping it means fixing it twice.
Carrying a second ecosystem's build system for an unbuilt, untested, unreleased binding is a maintenance tax with no consumer. If JVM support is wanted later it can come back as its own repo, against a stable ABI, without putting Gradle in this one's tree.
2. Bring the C core level with the managed parser
core/ is behind src/Glyph11 in three specific ways:
glyph11_limits is missing a field. Managed ParserLimits gained MaxReasonPhraseLength (default 512) in #56; the C struct still has seven fields ending at max_total_header_bytes. The struct carries struct_size for exactly this reason, so adding max_reason_phrase_len is additive and ABI-safe for existing callers.
There is no response parser. core/src/glyph11.c contains no occurrence of response or status_line, and glyph11.h exposes only glyph11_request. After #56 the managed parser reads responses and the C core cannot, which breaks the claim in the README:
All three produce the same data; Glyph11 and Glyph11.Pico fill the identical BinaryRequest, so swapping between them is a one-line change.
That is no longer true for anyone parsing responses - Glyph11.Native and Glyph11.Pico simply cannot.
glyph11_abi_version() needs a bump once the limits struct grows.
3. The thing that would have caught this
core/diff/ runs every input through both parsers and asserts identical results - outcome, status code, method/path/version bytes, headers, query pairs, consumed count. It is the mechanism that keeps C and C# honest, and it is request-only: it drives glyph11_parse_request against UltraHardenedParser and nothing else.
So response drift between the two implementations is currently invisible by construction. Whatever is done about the response parser in C, the diff harness should grow response vectors at the same time - otherwise the next divergence is found by a user rather than by CI.
Suggested order
- Delete
bindings/kotlin/ (nothing depends on it).
- Add
max_reason_phrase_len to glyph11_limits, bump glyph11_abi_version().
- Implement the response parser in the C core.
- Extend
core/diff/ with response vectors before, not after.
Two pieces of non-managed surface have drifted away from
src/Glyph11. Filing them together because they are the same shape: code outside the managed parser that nothing forces to keep up.1. Drop the Kotlin bindings
bindings/kotlin/is a Panama FFM binding overlibglyph11- two Kotlin files (Glyph11.kt,Main.kt) plus a full Gradle toolchain (gradlew,gradlew.bat,gradle/wrapper/,build.gradle.kts,settings.gradle.kts).Why it should go:
.github/workflows/references gradle or kotlin -build.yml,core-tests.yml,sonar.yml,package-native.yml,package-pico.ymlandrelease.ymlare all .NET or C. There is no automated proof it still compiles.Glyph11,Glyph11.Native,Glyph11.Pico- and Kotlin is none of them.Carrying a second ecosystem's build system for an unbuilt, untested, unreleased binding is a maintenance tax with no consumer. If JVM support is wanted later it can come back as its own repo, against a stable ABI, without putting Gradle in this one's tree.
2. Bring the C core level with the managed parser
core/is behindsrc/Glyph11in three specific ways:glyph11_limitsis missing a field. ManagedParserLimitsgainedMaxReasonPhraseLength(default 512) in #56; the C struct still has seven fields ending atmax_total_header_bytes. The struct carriesstruct_sizefor exactly this reason, so addingmax_reason_phrase_lenis additive and ABI-safe for existing callers.There is no response parser.
core/src/glyph11.ccontains no occurrence ofresponseorstatus_line, andglyph11.hexposes onlyglyph11_request. After #56 the managed parser reads responses and the C core cannot, which breaks the claim in the README:That is no longer true for anyone parsing responses -
Glyph11.NativeandGlyph11.Picosimply cannot.glyph11_abi_version()needs a bump once the limits struct grows.3. The thing that would have caught this
core/diff/runs every input through both parsers and asserts identical results - outcome, status code, method/path/version bytes, headers, query pairs, consumed count. It is the mechanism that keeps C and C# honest, and it is request-only: it drivesglyph11_parse_requestagainstUltraHardenedParserand nothing else.So response drift between the two implementations is currently invisible by construction. Whatever is done about the response parser in C, the diff harness should grow response vectors at the same time - otherwise the next divergence is found by a user rather than by CI.
Suggested order
bindings/kotlin/(nothing depends on it).max_reason_phrase_lentoglyph11_limits, bumpglyph11_abi_version().core/diff/with response vectors before, not after.