Skip to content

Release 0.10.0: the quiet minor (FIPS in CI, SBOM at release, the em-dash sweep) - #73

Merged
HackTuah merged 5 commits into
mainfrom
slice/043-release-0-10-0
Sep 23, 2026
Merged

HackTuah merged 5 commits into
mainfrom
slice/043-release-0-10-0

Conversation

@HackTuah

@HackTuah HackTuah commented Sep 23, 2026

Copy link
Copy Markdown
Member

Release 0.10.0, the quiet minor again. No public entry moves (release_markers!("0.10.0") wrote 0; docs/public-api.txt is unchanged). No wire or envelope byte moves: the recording's ten version lines are the only lines re-taken, and every canonical golden is 0.9.0's.

Commits, in order:

  1. The em-dash sweep. None is left outside the archived slices/, the CHANGELOG's released headings included. Pinned pairs moved together.
  2. README "Scheduled". Federation and effective connectivity move after 1.0.0. The Tasks extension is named third.
  3. The FIPS leg (.github/workflows/fips.yml). OTP 28.1.1 built with --enable-fips, over OpenSSL 3.5.8 with the 3.1.2 FIPS provider (CMVP #4985).
    • FIPS mode is asserted inside the VM before any test runs, with a negative control.
    • docs/fips.md now reports the measurements, and one claim is corrected: without the provider, a release still boots, and the first :crypto call raises.
  4. The SBOM at release. tools/sbom.sh uses the EEF's mix_sbom, pinned by digest, outside mix.exs. It is attested to the tarball's digest.
    • The workflow downloads the SBOM back and compares it with what it generated.
    • One workaround is named: mix_sbom 0.11.0 cannot read tools: :optional. A fix is being offered upstream.
    • The threat model's supply-chain row now states what shipped.
  5. The release commit. The version, the CHANGELOG cut, the README pin (~> 0.10.0) and requirement test, SECURITY, UPGRADING, the roadmap, the provenance examples and HANDOFF.

Measured

  • Gate on b036b70: Gate OK, all sixteen steps pass. The baseline holds 135 entries, none deleted, and 0 markers arrive.
  • Locally: 11 properties, 729 tests, 0 failures.
  • In FIPS mode, locally on the workflow's toolchain: 11 properties, 729 tests, 0 failures.
  • SBOM loop in CI (dispatch run 35923135790): generated (16 bom-refs), attested, verified, and downloaded back equal.
  • Canonical tarball from b036b70: sha256 4901468b41bd594181879835c5865c318cf2d53995eceff9f3c39c2e92a109c1. Identical on ext4 and tmpfs.

The maintainer tags and publishes after the merge, in the 0.6.0 order: tag locally, then tools/release_tarball.sh v0.10.0 beam_mcp-0.10.0.tar --publish, then push the tag.

…s released headings included

The owner's ask: the public tree clean of em dashes by 1.0.0. Measured on 58bcde6: 817 lines
outside slices/ carried one; after: `git grep -c` finds none, and no added line carries one.
Punctuation by judgement, sentence by sentence: a colon before an explanation or a list, commas
or parentheses around an aside, a semicolon or full stop between clauses, `--` in code comments
(the style already in use). No meaning, number, code span or link moves. En dashes (ranges) are
untouched. slices/ is not swept: its 243 grandfathered files are sha256-pinned records, not in
the tarball (the one exception, for the owner's word).

Decided for the owner's two open points (CX-145): the CHANGELOG's released headings and entries
are swept too (`## [0.8.0] - 2026-09-19`, `### Added: ...`, `### Changed (BREAKING): ...`, the
0.9.0 form), since each released tarball keeps its own copy and git keeps history; UPGRADING's
quotations of those headings move identically (each still matches exactly one CHANGELOG line).
The internal repository is left alone.

Pairs moved together: the README's "boundary (twelve entries" and will_not_implement_test's
assert; the threat model's two cited test titles and http_test ("Origin: a second, disallowed
Origin is not ignored", "Mcp-Param-{Name}: a second, disagreeing value is not ignored"); the
:authorize_body/2 describe title and the readme_claims comment quoting it; public_api_census
fixtures for the new heading forms; the README's range-check regex keeps refusing an em-dash
range by naming the character as \x{2014}. Empty table cells that held a dash read "none". The
CHANGELOG's quotation of mutate.sh's row now matches what the tool prints
(`COMPILER-KILL -- not a kill`, tools/mutate.sh:169). lib/: docstrings and comments only; no
runtime string changed. The heading parsers (tools/baseline_diff.sh, test/support/public_api.ex,
docs_census_test) read `## [x.y.z]` and `### ` and still do.

Signed-off-by: Ayla Croft <aylacroft@proton.me>
…ve connectivity after 1.0.0; Tasks named

The README scheduled the federation seam and effective connectivity 'at the minor position while
the package is 0.x', ahead of 1.0.0; UPGRADING's road (0.10.0, then 1.0.0) and the stand both
place them after 1.0.0. The paragraph now says so: 1.0.0's condition first, then the three
additions in order, the third being the Tasks extension of the 2026-07-28 revision, which had
no row anywhere (G-082), stated as not built and not refused. docs/roadmap.md lists it third.
Copy only; readme_claims, docs_census, will_not_implement, publication_content: 39 tests, 0
failures.

Signed-off-by: Ayla Croft <aylacroft@proton.me>
…er; docs/fips.md measured, and corrected

0.10.0's instrument (the roadmap's "FIPS leg"). A separate workflow, not a leg of the gate's
matrix: the quality gate's contexts and the ruleset do not move. OTP 28.1.1 --enable-fips over
OpenSSL 3.5.8 libcrypto with the FIPS provider from 3.1.2 (CMVP #4985's source, its security
policy's section 11.1 steps), downloads checked against published SHA-256s (OpenSSL's, OTP's
SHA256.txt, Hex's builds.txt for Elixir 1.18.4-otp-28), cached; deps and compile with FIPS off,
the suite with -crypto fips_mode true, asserted in the same VM with the load in its own -e (a
same-expression check reads a crypto loaded before fips_mode applied: the research agent
measured it passing with FIPS off). Negative control first. Public repository: no billed minutes.

Measured locally on that exact toolchain before writing a line of the page: info_fips :enabled,
fips_provider_available true, buildinfo "3.1.2", linked "OpenSSL 3.5.8 25 Aug 2026"; md5
{notsup, "Bad digest type in FIPS"}; sha256("abc") = BA7816BF...15AD; sha384/512 48/64 bytes;
the suite 11 properties, 729 tests, 0 failures in 26 s; without the provider configuration the
same command exits 1 before any test (crypto's on_load fails); fips_mode unset answers
:not_enabled. OTP built in 37 s at -j16 here; CI at -j4 will be slower.

The measurement corrected the page: it said a release requesting FIPS mode without a provider
does not boot because application:start(crypto) fails. Measured: application:start(crypto) and
ensure_all_started answer ok and the module is not loaded, so the release boots and the first
:crypto call raises UndefinedFunctionError. Step 3 (check at start) is now why, not a belt.
No test pinned fips.md (grep test/ tools/ lib/ for fips: none).

Signed-off-by: Ayla Croft <aylacroft@proton.me>
…ol, attested to the tarball

0.10.0's second instrument, under the owner's 024b constraints: the EEF's tool, not a
dependency; nothing added to mix.lock; attached at release, not kept in the tree; the licence
set read first (sbom 0.11.0: BSD-3-Clause, CC0-1.0, MIT, Apache-2.0; its dependencies hex_core
Apache-2.0, optimus MIT, protobuf MIT, purl Apache-2.0, jason Apache-2.0 -- none of it ships
with this package, it only runs in CI). tools/sbom.sh downloads the mix_sbom 0.11.0 Linux
binary, checks it against the SHA-256 GitHub records for the release asset (db1982c8...d572de),
reads a git archive of the ref after mix deps.get, --only prod. provenance.yml runs it after the
build, attests it with actions/attest v4.2.2 (1e69f48a, the tag's commit) to the same tarball
digest, verifies it with --predicate-type https://cyclonedx.org/bom, then downloads it back as
docs/provenance.md instructs and compares the predicate with the generated file.

G-087, named in the script: mix_sbom 0.11.0 crashes on `tools: :optional` in
extra_applications (normalize_dep/1). The scratch copy's line reads `:tools`; the script
refuses to run if the line is not exactly the one it rewrites. Upstream issue + patch drafted.

Measured locally on this tree: "CycloneDX 1.6, 16 bom-refs" -- bandit 1.12.5, hpax 1.0.4,
jason 1.4.5, mime 2.0.7, plug 1.20.3, plug_crypto 2.2.0, telemetry 1.4.2, thousand_island
1.5.0, websock 0.5.3, and crypto, elixir, kernel, logger, stdlib, tools; bomFormat,
serialNumber and specVersion present (what actions/attest detects). Not measured here: the
attest/download round trip (gh 2.45 has no attestation command); a workflow_dispatch run on
this branch measures it before the release merges.

The threat model's supply-chain row reads what shipped. provenance, governance, threat_model
tests: 32 tests, 0 failures.

Signed-off-by: Ayla Croft <aylacroft@proton.me>
…t release, the pages); no public entry moves

The version (0.9.0 -> 0.10.0). release_markers!("0.10.0") on docs/public-api.txt wrote 0: the
file carries no Unreleased marker and did not move, so no public entry was added, removed,
renamed, hidden or changed in arity. The CHANGELOG's Unreleased section cut as
[0.10.0] - 2026-09-23 with a paragraph naming the quiet minor, what it carries and the road,
and an entry for the sweep and the README's Scheduled paragraph; Unreleased is empty. README:
the requirement ~> 0.10.0 and its paragraph (0.10.0 a quiet minor again; ~> 0.10 would admit a
0.11.0); the requirement test refuses 0.9.0, 0.8.0, 0.7.0 and 0.6.0 with true reasons, and 0.5.0
and 0.4.0 across their breaks as before. SECURITY: 0.10.x yes, 0.9.x superseded. api-stability's
example command and current-minor pin. UPGRADING: the pin, a "no row" paragraph for 0.10.0 in
0.8.0's shape, the road (0.9.0 no longer "this release"; 0.10.0 this release). docs/roadmap.md:
"Now: 0.10.0", "Next: 1.0.0". docs/provenance.md's examples at 0.10.0 (they said 0.7.0).
HANDOFF for the release (State, What is next, the runbook heading, git log v0.9.0..main).

The wire recording re-taken at 0.10.0: git diff 10 insertions, 10 deletions, every one a
"version" line; wire_recording_test 2 tests, 0 failures. `git diff v0.9.0 --
test/fixtures/connectome/ docs/public-api.txt` is empty: every canonical golden is 0.9.0's blob.

Measured before this commit: the SBOM loop in CI (workflow_dispatch run 35923135790 on this
branch: tarball, provenance attestation 49670828, SBOM "CycloneDX 1.6, 16 bom-refs",
attestation 49670848, verify --predicate-type https://cyclonedx.org/bom, and "the downloaded
SBOM predicate equals the generated document"); the FIPS suite locally on the workflow's
toolchain (11 properties, 729 tests, 0 failures). The owner publishes and tags, in the 0.6.0
order; this commit does neither.

Signed-off-by: Ayla Croft <aylacroft@proton.me>
@HackTuah
HackTuah marked this pull request as ready for review September 23, 2026 21:37
@HackTuah
HackTuah merged commit 027fcc9 into main Sep 23, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant