Fix pre-release review findings: dist AmiSSL guard, TLS handshake hangs, doc drift - #19
Merged
Conversation
…gs, doc drift Four independent reviewers (correctness, release mechanics, docs, Amiga pitfalls) went over the repo before the next tag. Two release blockers and several should-fixes, all fixed here and re-verified: Release blockers: - Makefile: `make dist` neither fetched the AmiSSL SDK nor required it, so a fresh checkout (exactly what release.yml's dist job does) would silently link a TLS-less mqtt.library while midge.readme advertises TLS as shipped. `dist` now fetches the SDK itself if missing and re-invokes `build` as a sub-make (M68K_HAS_AMISSL is a `:=` immediate-expansion variable, fixed at outer-make parse time - only a fresh sub-make process re-evaluates it against the now-populated .cache/), then hard-fails if the resulting mqtt.library still has no AmiSSL support - a permanent mechanical guard against this whole class of regression, not just a one-time fix. Verified: ran `make dist` for real inside the CI container from a clean .cache/, confirmed the AmiSSL-presence grep both passes on a real TLS build and correctly fails a deliberately non-TLS one. - src/amiga/transport_amissl.c: the TLS handshake loop had no deadline and, inside mqtt.library's connection subprocess, no way to abort - break_sigmask is only wired up *after* connect() returns, and wait_gate() deliberately treats a break_sigmask wake as a retry, not an abort. A peer that accepts the TCP connect but stalls the handshake (tarpit, wrong service on the port, wedged broker) hung the caller forever with no recovery short of a reboot - MQTT_Disconnect()/ MQTT_DeleteClient() couldn't reach the wedged child either. Added a 30s elapsed-time budget (tool_now_ms()) to the loop. Re-verified both on-target smoke tests (library-tls-smoke, library-cafile-smoke) still pass end-to-end against real AmiSSL under Copperline. Also fixed (real defect, not blocking): - src/host/transport_openssl.c: a single SSL_connect() call on a blocking socket with a 1s SO_RCVTIMEO can return SSL_ERROR_WANT_READ when a read hits that timeout - blocking mode doesn't change what OpenSSL reports, only whether recv() itself blocks. One lost packet mid-handshake or a slow broker made `mqtt_pub -s` fail spuriously. Added the same bounded WANT_READ/WANT_WRITE retry loop (30s budget) transport_amissl.c already had to have. Re-verified: broker-tls-smoke passes (verify-on, skip-verify, and untrusted-cert-rejected cases). - scripts/verify-version.sh (issue #9): now also checks MIDGE_VERSION_DATE actually changed since the previous release tag (format-validated too), closing the gap where a release PR bumping MIDGE_VERSION but forgetting the date would pass every existing check and ship binaries whose $VER carries the previous release's date. Verified against three cases: real bump (passes), version bumped with date left stale (fails with the new check), version unchanged (unaffected). Docs drift: - userdocs/CLI-Reference.md: the ReadArgs template code blocks were missing TLS/TLSINSECURE/CAFILE even though the argument tables right below them documented all three; "two flags that only exist on the host builds so far" was stale twice over (three flags, and no longer host-only since the Amiga transport shipped). - README.md: the Status/Features sections still said TLS "is next" and pointed at docs/ARCHITECTURE.md's roadmap section, which was deliberately trimmed to shipped history and no longer covers post-v0.1 work (that's tracked via GitHub issues now, as the file itself says). - userdocs/mqtt-library.md: never mentioned mco_TLS/mco_TLSInsecure/ mco_CAFile at all; the error-code table was missing MQTTERR_STATE (-205) and mischaracterized MQTTERR_NOSTACK as something that can actually be returned (it's reserved - MQTT_CreateClient() returns a bare NULL on every creation failure). Added a TLS section, including the one real semantic difference from the CLI worth calling out: mco_TLSInsecure does NOT imply mco_TLS the way TLSINSECURE/-S implies TLS/-s on the CLI - it's simply ignored without mco_TLS set. Deliberately not changed, for the user to decide: - The actual version bump (0.1 -> next) - that's its own release PR per CLAUDE.md's process, not something to fold into a fixes PR. - Enabling `run-dist: true` in ci.yml's per-push CI (would have caught the dist blocker earlier, but changes CI cost/cadence - a judgment call, not a fix). - wait_gate()'s theoretical WaitSelect-failure misclassification and transport_openssl.c's low-confidence stale-errno edge case in openssl_recv() - both flagged as pre-existing patterns/unconfirmed triggers by the reviewers themselves, not concrete bugs. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QWq1CRLCQy9AaD9UtLRSM9
This was referenced Aug 30, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Four independent reviewers (correctness, release mechanics, docs, Amiga-platform pitfalls) went over the repo ahead of the next tag. This fixes everything found except three items called out below as deliberately left for a decision/separate PR.
Release blockers (fixed + verified)
make distcould silently ship a TLS-lessmqtt.library.distdidn't fetch the AmiSSL SDK or require it - a fresh checkout (whatrelease.yml's dist job does) would build without TLS whilemidge.readmeadvertises it as shipped. Fixed:distnow fetches the SDK if missing and re-invokesbuildas a sub-make (a plain prerequisite wouldn't work -M68K_HAS_AMISSLis fixed at outer-make parse time, before any recipe including the fetch runs), then hard-fails if the built library still lacks AmiSSL - a permanent mechanical guard, not a one-time patch. Verified: ranmake distfor real from a clean.cache/inside the CI container; confirmed the guard passes a real TLS build and fails a deliberately non-TLS one.mqtt.library's connection subprocess nothing could abort it (break_sigmaskwired up only after connect returns;wait_gate()treats a break wake as retry-me, not abort). A stalled peer (tarpit, wrong service on the port) wedged the caller with no recovery short of reboot. Fixed: 30s elapsed-time budget. Verified:library-tls-smokeandlibrary-cafile-smokeboth still pass end-to-end against real AmiSSL under Copperline.Real defect (not release-blocking, fixed anyway)
transport_openssl.c'sSSL_connect()was single-shot. A blocking socket with 1sSO_RCVTIMEOcan still returnSSL_ERROR_WANT_READon a timed-out read; one lost packet mid-handshake mademqtt_pub -sfail spuriously. Added the same bounded retry loop the AmiSSL transport already needed. Verified:broker-tls-smokepasses (verify-on, skip-verify, untrusted-cert-rejected).verify-version.shnow checksMIDGE_VERSION_DATEactually changed since the previous tag (plus format validation) - closes the gap where a release PR bumps the version but forgets the date. Verified against three simulated cases (real bump, stale-date bump, unchanged).Docs drift (fixed)
CLI-Reference.md: ReadArgs template code blocks were missingTLS/TLSINSECURE/CAFILEeven though the tables right below documented them; "two flags that only exist on the host builds" was stale twice over.README.md: Status/Features still said TLS "is next" and pointed atdocs/ARCHITECTURE.md's roadmap, which was deliberately trimmed and no longer covers post-v0.1 work.mqtt-library.md: never mentionedmco_TLS/mco_TLSInsecure/mco_CAFile; error-code table was missingMQTTERR_STATEand mischaracterizedMQTTERR_NOSTACK. Added a TLS section, including the one real CLI/library semantic difference worth flagging:mco_TLSInsecuredoes not implymco_TLSthe way the CLI'sTLSINSECUREimpliesTLS.Deliberately not changed
CLAUDE.md.run-dist: trueon per-push CI - would've caught blocker Configure Renovate #1 earlier, but changes CI cost/cadence; a judgment call for you, not folded in here.wait_gate()'s theoreticalWaitSelect-failure misclassification andtransport_openssl.c's low-confidence stale-errno edge case - both flagged by reviewers as pre-existing patterns / unconfirmed triggers, not concrete bugs.Test plan
make test- 249/249 host unit tests pass.make broker-smoke/make broker-tls-smoke- all pass, including the SSL_connect retry-loop fix.make lint,make m68k,make test-target(real m68k codegen under Copperline) - all clean.sh tests/library/tls-run.sh,sh tests/library/cafile-run.sh- full green on-target against real AmiSSL.make distfrom a clean.cache/- real end-to-end run inside the CI container; AmiSSL-presence guard verified both ways (passes real build, fails a forced non-TLS build).scripts/verify-version.sh- tested against a real bump, a stale-date bump (correctly fails), and an unchanged version (correctly passes).mkdocs build --strictanddocs2guide.pyconversion both clean after the docs fixes.🤖 Generated with Claude Code
https://claude.ai/code/session_01QWq1CRLCQy9AaD9UtLRSM9