Skip to content

Commit bd3a7bb

Browse files
committed
Merge branch 'main' into slice/132-control-mapping
Signed-off-by: Ayla Croft <aylacroft@proton.me>
2 parents 69cbfe8 + ea3fa35 commit bd3a7bb

42 files changed

Lines changed: 1558 additions & 92 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/fips-image.yml‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ on:
1212
push:
1313
paths:
1414
- .tool-versions
15+
- ci/container.tool-versions
1516
- ci/fips/Containerfile
1617
- scripts/fips_image_tag.sh
1718
- .github/workflows/fips-image.yml
@@ -34,11 +35,13 @@ jobs:
3435
steps:
3536
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
3637

37-
- name: The tag, and the versions .tool-versions names
38+
# OTP is the container's (ci/container.tool-versions), which may lead the desktop's pin in
39+
# .tool-versions (ADR-0014); Elixir is the one Elixir pin.
40+
- name: The tag, the container's OTP and the Elixir .tool-versions names
3841
id: meta
3942
run: |
4043
echo "ref=$(scripts/fips_image_tag.sh --ref)" >> "$GITHUB_OUTPUT"
41-
echo "otp=$(awk '$1 == "erlang" { print $2 }' .tool-versions)" >> "$GITHUB_OUTPUT"
44+
echo "otp=$(awk '$1 == "erlang" { print $2 }' ci/container.tool-versions)" >> "$GITHUB_OUTPUT"
4245
echo "elixir=$(awk '$1 == "elixir" { print $2 }' .tool-versions | cut -d- -f1)" >> "$GITHUB_OUTPUT"
4346
4447
- name: Log in to the registry

‎.github/workflows/gate.yml‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,8 @@ jobs:
212212
sleep 30
213213
done
214214
echo "::error::$ref was not published within 30 minutes. It is built by the" \
215-
"fips-image workflow, which runs when ci/fips/Containerfile, .tool-versions or" \
215+
"fips-image workflow, which runs when ci/fips/Containerfile, .tool-versions," \
216+
"ci/container.tool-versions or" \
216217
"scripts/fips_image_tag.sh changes. Check that workflow's run for this commit."
217218
exit 1
218219

‎.github/workflows/headless-image.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ on:
3232
- mix.lock
3333
- config/**
3434
- .tool-versions
35+
- ci/container.tool-versions
3536
- .github/workflows/headless-image.yml
3637
schedule:
3738
- cron: "17 6 * * *"

‎.github/workflows/otp-canary.yml‎

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# SPDX-FileCopyrightText: Sudo Apt Holdings LLC
2+
# SPDX-License-Identifier: Apache-2.0
3+
#
4+
# The OTP canary (owner decision D2, ADR-0014). The desktop pin in .tool-versions waits for
5+
# Burrito's ERTS builds; the container pin in ci/container.tool-versions does not. Every day this
6+
# asks whether Burrito can now fetch the container's OTP for all three desktop targets, and the
7+
# first day it can, it opens a pull request that moves the desktop pin there. Merging that pull
8+
# request is how the desktop gets the CVE-2026-89422 fix, and with it `Trinity.TLS` stops holding
9+
# the desktop's TLS clients to TLS 1.2 (it decides from the running runtime, not from a flag).
10+
#
11+
# Two things a reader of the pull request needs to know:
12+
# * a pull request opened with GITHUB_TOKEN starts no workflow, so its gate runs when a person
13+
# pushes to the branch (or closes and reopens it);
14+
# * the repository setting "Allow GitHub Actions to create and approve pull requests" must be on,
15+
# or the last step fails with a permissions error that names it.
16+
# It never opens a second pull request for the same version: a closed one is a person's answer.
17+
name: otp-canary
18+
19+
on:
20+
schedule:
21+
- cron: "41 7 * * *"
22+
workflow_dispatch:
23+
24+
permissions:
25+
contents: read
26+
27+
jobs:
28+
probe:
29+
runs-on: ubuntu-latest
30+
outputs:
31+
result: ${{ steps.probe.outputs.result }}
32+
version: ${{ steps.probe.outputs.version }}
33+
steps:
34+
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
35+
36+
- name: Can Burrito fetch the container's OTP for every desktop target?
37+
id: probe
38+
run: scripts/otp_canary.sh probe | tee -a "$GITHUB_OUTPUT"
39+
40+
flip:
41+
needs: probe
42+
if: needs.probe.outputs.result == 'ready'
43+
runs-on: ubuntu-latest
44+
# The branch push and the pull request, and nothing else in this workflow.
45+
permissions:
46+
contents: write
47+
pull-requests: write
48+
env:
49+
VERSION: ${{ needs.probe.outputs.version }}
50+
BRANCH: canary/otp-${{ needs.probe.outputs.version }}
51+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
52+
steps:
53+
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
54+
55+
- name: Has a pull request for this version been opened before?
56+
id: seen
57+
run: |
58+
count=$(gh pr list --head "$BRANCH" --state all --json number --jq length)
59+
if [ "$count" != 0 ] || git ls-remote --exit-code --heads origin "$BRANCH" >/dev/null; then
60+
echo "::notice::$BRANCH already has a pull request or a branch; nothing to do"
61+
echo "seen=true" >> "$GITHUB_OUTPUT"
62+
else
63+
echo "seen=false" >> "$GITHUB_OUTPUT"
64+
fi
65+
66+
# The flip first, so setup-beam installs the OTP the pull request moves to: the licence list
67+
# names the OTP applications of the runtime that generates it, and VERSIONS.md is generated
68+
# from the pin list the flip edits. The gate checks both.
69+
- name: Move the desktop pin
70+
if: steps.seen.outputs.seen == 'false'
71+
run: scripts/otp_canary.sh flip
72+
73+
- uses: erlef/setup-beam@54075bcc5e249e4758d363f27d099f55d843f124 # v1.24.1
74+
if: steps.seen.outputs.seen == 'false'
75+
with:
76+
version-file: .tool-versions
77+
version-type: strict
78+
79+
- uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
80+
if: steps.seen.outputs.seen == 'false'
81+
with:
82+
path: |
83+
deps
84+
_build
85+
key: ${{ runner.os }}-mix-canary-${{ hashFiles('mix.lock') }}
86+
restore-keys: ${{ runner.os }}-mix-
87+
88+
- name: Regenerate VERSIONS.md and THIRD_PARTY_LICENSES.md on the new OTP
89+
if: steps.seen.outputs.seen == 'false'
90+
env:
91+
MIX_ENV: test
92+
run: |
93+
mix deps.get
94+
mix versions.gen
95+
mix trinity.sbom
96+
mix trinity.third_party_licenses --write
97+
98+
- name: Open the pull request
99+
if: steps.seen.outputs.seen == 'false'
100+
run: |
101+
git config user.name "github-actions[bot]"
102+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
103+
git switch -c "$BRANCH"
104+
git commit -s -a -m "build(otp): move the desktop pin to OTP $VERSION (ADR-0014)"
105+
git push origin "$BRANCH"
106+
cat > "$RUNNER_TEMP/body.md" <<EOF
107+
Burrito can now fetch OTP $VERSION for every desktop target (the probe in this run's
108+
log), so the desktop pin in \`.tool-versions\` moves to the container's pin.
109+
110+
What this changes: the desktop runs an OTP with the CVE-2026-89422 fix, and
111+
\`Trinity.TLS\` stops holding its TLS clients to TLS 1.2 on its own.
112+
113+
Before merging, by hand:
114+
- push a commit to this branch so the gate runs (a pull request opened by a workflow
115+
starts none);
116+
- update the Erlang/OTP row's note in \`lib/trinity/versions.ex\`, then \`mix versions.gen\`
117+
(the pin itself, \`VERSIONS.md\` and \`THIRD_PARTY_LICENSES.md\` are already moved);
118+
- update the OTP lines in \`README.md\` and \`docs/packaging.md\`;
119+
- append the closing of the window to \`docs/adr/0014-otp-pins-split.md\`;
120+
- check the \`package\` workflow on all three targets.
121+
EOF
122+
gh pr create --base main --head "$BRANCH" \
123+
--title "build(otp): move the desktop pin to OTP $VERSION" \
124+
--body-file "$RUNNER_TEMP/body.md"

‎.tool-versions‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
erlang 28.5.0.5
1+
erlang 28.5.0.6
22
elixir 1.20.4-otp-28
33
zig 0.16.0

‎CHANGELOG.md‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,16 @@ disposition. The scanner was chosen by measurement: of the two tried, only grype
6262
runtime inside a release. The image is not in Iron Bank and this is not a compliance determination;
6363
`docs/regulated/headless-image.md` says what it is, how to check it, and what is still open.
6464

65+
The image builds Erlang/OTP 28.5.0.7, which fixes CVE-2026-89422 (OTP's TLS 1.3 client could skip
66+
the server's certificate) and the other OTP advisories the scan reported; the scan now finds none in
67+
the runtime. The desktop cannot have that version until Burrito publishes builds of it, so the
68+
container and the desktop now have separate OTP pins (ADR-0014). The desktop moves to 28.5.0.6, and
69+
while it runs an affected OTP every outbound TLS connection Trinity makes is held to TLS 1.2, the
70+
advisory's own workaround. A test reads every TLS client the release contains from its compiled code
71+
and checks what each one offers to a server on the wire, so a dependency that would open TLS 1.3
72+
fails the gate. A daily job opens the pull request that moves the desktop pin once the builds exist,
73+
and the clamp lifts itself when it does.
74+
6575
### `slice/100`: Trinity as a desktop application
6676

6777
The Tauri window now does what a desktop application is expected to do. A tray icon shows whether

‎README.md‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,10 @@ demonstrate, each tied to the slice that proves it.
199199

200200
## Running from source
201201

202-
Requires the pinned toolchain in `.tool-versions` (Erlang 28.5.0.5, Elixir 1.20.4, Zig 0.16.0),
203-
installed with `asdf install`. Rust 1.92.0 is pinned separately in `rust-toolchain.toml` and is
202+
Requires the pinned toolchain in `.tool-versions` (Erlang 28.5.0.6, Elixir 1.20.4, Zig 0.16.0),
203+
installed with `asdf install`. The container images build Erlang 28.5.0.7 from source
204+
(`ci/container.tool-versions`); the desktop's pin waits for Burrito's builds of it and, until then,
205+
holds every outbound TLS connection to TLS 1.2 (`docs/adr/0014-otp-pins-split.md`). Rust 1.92.0 is pinned separately in `rust-toolchain.toml` and is
204206
only needed for the desktop shell.
205207

206208
```

‎THIRD_PARTY_LICENSES.md‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,17 @@ it, and a reader should not infer from an entry here that the component is in a
2323
| `asn1` | `5.4.3` | Apache-2.0 | bom |
2424
| `axon` | `0.8.1` | Apache-2.0 | bom |
2525
| `bandit` | `1.12.5` | MIT | bom |
26-
| `beam_mcp` | `0.9.0` | Apache-2.0 | bom |
26+
| `beam_mcp` | `0.10.1` | Apache-2.0 | bom |
2727
| `boundary` | `0.10.4` | MIT | bom |
2828
| `bumblebee` | `0.7.1` | Apache-2.0 | bom |
2929
| `bunt` | `1.0.0` | MIT | bom |
3030
| `burrito` | `1.6.0` | MIT | bom |
3131
| `castore` | `1.0.21` | Apache-2.0 | bom |
3232
| `cc_precompiler` | `0.1.11` | Apache-2.0 | bom |
33-
| `compiler` | `9.0.6.1` | Apache-2.0 | bom |
33+
| `compiler` | `9.0.6.2` | Apache-2.0 | bom |
3434
| `complex` | `0.7.0` | Apache-2.0 | bom |
3535
| `credo` | `1.7.19` | MIT | bom |
36-
| `crypto` | `5.8.3.2` | Apache-2.0 | bom |
36+
| `crypto` | `5.8.3.3` | Apache-2.0 | bom |
3737
| `daisyui` | `22ecff57f2c3` | MIT | declared |
3838
| `db_connection` | `2.10.2` | Apache-2.0 | bom |
3939
| `decimal` | `3.1.1` | Apache-2.0 | bom |
@@ -66,12 +66,12 @@ it, and a reader should not infer from an entry here that the component is in a
6666
| `hpax` | `1.1.0` | Apache-2.0 | bom |
6767
| `idna` | `7.1.0` | MIT | bom |
6868
| `igniter` | `0.8.4` | MIT | bom |
69-
| `inets` | `9.6.2.2` | Apache-2.0 | bom |
69+
| `inets` | `9.6.2.3` | Apache-2.0 | bom |
7070
| `jason` | `1.4.5` | Apache-2.0 | bom |
7171
| `jcs` | `0.2.0` | Apache-2.0 | bom |
7272
| `jose` | `1.11.12` | MIT | bom |
7373
| `jsv` | `0.23.0` | Apache-2.0 | bom |
74-
| `kernel` | `10.6.3.3` | Apache-2.0 | bom |
74+
| `kernel` | `10.6.3.4` | Apache-2.0 | bom |
7575
| `lazy_html` | `0.1.13` | Apache-2.0 | bom |
7676
| `llm_db` | `2026.9.4` | Apache-2.0 | bom |
7777
| `logger` | `1.20.4` | Apache-2.0 | bom |
@@ -129,9 +129,9 @@ it, and a reader should not infer from an entry here that the component is in a
129129
| `sourceror` | `1.12.3` | Apache-2.0 | bom |
130130
| `spitfire` | `0.4.2` | MIT | bom |
131131
| `splode` | `0.3.2` | MIT | bom |
132-
| `ssh` | `5.5.2.4` | Apache-2.0 | bom |
133-
| `ssl` | `11.6.0.4` | Apache-2.0 | bom |
134-
| `stdlib` | `7.3.0.1` | Apache-2.0 | bom |
132+
| `ssh` | `5.5.2.5` | Apache-2.0 | bom |
133+
| `ssl` | `11.6.0.5` | Apache-2.0 | bom |
134+
| `stdlib` | `7.3.0.2` | Apache-2.0 | bom |
135135
| `stream_data` | `1.4.0` | Apache-2.0 | bom |
136136
| `tailwind` | `0.5.1` | MIT | bom |
137137
| `telemetry` | `1.4.2` | Apache-2.0 | bom |

0 commit comments

Comments
 (0)