88
99env :
1010 CARGO_TERM_COLOR : always
11+ MESH_MATRIX_VOICE_FRONTEND : matrix-voice
1112
1213permissions :
14+ actions : read
1315 contents : read
1416
1517jobs :
2123 matrix :
2224 os : [ubuntu-latest, windows-latest]
2325 steps :
24- - uses : actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
26+ - uses : actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
2527
2628 - name : Install Rust toolchain
2729 uses : dtolnay/rust-toolchain@d0befba8b9ddf874327619e84c39b094edd58b66 # 1.93.0
4143 libsqlcipher-dev
4244
4345 - name : Cache cargo registry & build
44- uses : actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
46+ uses : actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
4547 with :
4648 path : |
4749 ~/.cargo/registry
@@ -74,11 +76,17 @@ jobs:
7476 working-directory : mesh/src-tauri
7577 run : cargo test --no-default-features --features matrix-backend --locked --jobs 1
7678
79+ - name : Check and test signed-candidate Matrix voice backend
80+ working-directory : mesh/src-tauri
81+ run : |
82+ cargo check --no-default-features --features matrix-voice --locked --jobs 1
83+ cargo test --no-default-features --features matrix-voice --locked --jobs 1
84+
7785 legacy-rust :
7886 name : Legacy LAN Rust
7987 runs-on : ubuntu-latest
8088 steps :
81- - uses : actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
89+ - uses : actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
8290
8391 - name : Install Rust toolchain
8492 uses : dtolnay/rust-toolchain@d0befba8b9ddf874327619e84c39b094edd58b66 # 1.93.0
95103 libsqlcipher-dev
96104
97105 - name : Cache cargo registry & legacy build
98- uses : actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
106+ uses : actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
99107 with :
100108 path : |
101109 ~/.cargo/registry
@@ -120,18 +128,21 @@ jobs:
120128 name : Frontend Build & Browser E2E
121129 runs-on : ubuntu-latest
122130 steps :
123- - uses : actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
131+ - uses : actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
124132 with :
125133 # The readiness validator binds sourceTreeHash to an exact historical
126134 # sourceCommit, so a synthetic depth-one PR merge is insufficient.
127135 fetch-depth : 0
128136
129137 - name : Setup Node.js
130- uses : actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
138+ uses : actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
131139 with :
132140 node-version : 22
133141 cache : npm
134- cache-dependency-path : mesh/package-lock.json
142+ cache-dependency-path : |
143+ mesh/package-lock.json
144+ mesh/feature-deps/matrix-voice/package-lock.json
145+ mesh/feature-deps/legacy-lan/package-lock.json
135146
136147 - name : Install dependencies
137148 working-directory : mesh
@@ -157,14 +168,18 @@ jobs:
157168 working-directory : mesh
158169 run : npm run check:icons
159170
171+ - name : Check bundled interface sounds
172+ working-directory : mesh
173+ run : npm run check:interface-sounds
174+
160175 - name : Check reviewed public services
161176 working-directory : mesh
162177 run : npm run check:public-services
163178
164- - name : Check production readiness ledger
179+ - name : Check protected evidence and production readiness ledger
165180 working-directory : mesh
166181 run : |
167- node --test scripts/ check-readiness-ledger.test.mjs
182+ npm run check:protected-evidence
168183 npm run check:readiness-ledger
169184
170185 - name : Check fail-closed external acceptance contract
@@ -177,6 +192,10 @@ jobs:
177192 working-directory : mesh
178193 run : npm run check:public-site
179194
195+ - name : Check approved owner decisions
196+ working-directory : mesh
197+ run : npm run check:owner-decisions
198+
180199 - name : Check beta product boundary
181200 working-directory : mesh
182201 run : npm run check:beta-contract
@@ -206,13 +225,23 @@ jobs:
206225 working-directory : mesh
207226 run : npm run test -- --maxWorkers=4
208227
209- - name : Build frontend
228+ - name : Test isolated voice dependency graphs
229+ working-directory : mesh
230+ run : npm run test:voice-features
231+
232+ - name : Build non-shipping comparison frontends
233+ working-directory : mesh
234+ run : |
235+ npm run build:lan
236+ npm run build:matrix
237+
238+ - name : Build signed-candidate Matrix voice frontend
210239 working-directory : mesh
211- run : npm run build
240+ run : npm run build:matrix-voice
212241
213242 - name : Enforce frontend entry bundle budget
214243 working-directory : mesh
215- run : npm run check:bundle-size
244+ run : npm run check:bundle-size -- --report release/bundle-report.json
216245
217246 - name : Install Playwright browser
218247 working-directory : mesh
@@ -221,3 +250,64 @@ jobs:
221250 - name : Run browser E2E tests and WCAG scans
222251 working-directory : mesh
223252 run : npm run e2e
253+
254+ protected-evidence :
255+ name : Protected CI evidence manifest
256+ if : always()
257+ needs : [matrix-rust, legacy-rust, check-frontend]
258+ runs-on : ubuntu-latest
259+ steps :
260+ - uses : actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
261+ with :
262+ fetch-depth : 0
263+ - uses : actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
264+ with :
265+ node-version : 22
266+ - name : Fail closed unless every protected job passed
267+ env :
268+ MATRIX_RUST : ${{ needs.matrix-rust.result }}
269+ LEGACY_RUST : ${{ needs.legacy-rust.result }}
270+ FRONTEND : ${{ needs.check-frontend.result }}
271+ run : |
272+ node mesh/scripts/protected-ci-results.mjs
273+ - name : Upload protected CI payload
274+ id : payload
275+ uses : actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
276+ with :
277+ name : ci-r0-payload-${{ github.sha }}
278+ path : mesh/release/ci-run-results.json
279+ if-no-files-found : error
280+ retention-days : 90
281+ - name : Resolve protected CI payload archive size
282+ id : payload-metadata
283+ env :
284+ GH_TOKEN : ${{ github.token }}
285+ ARTIFACT_ID : ${{ steps.payload.outputs.artifact-id }}
286+ run : echo "size=$(gh api repos/${GITHUB_REPOSITORY}/actions/artifacts/${ARTIFACT_ID} --jq .size_in_bytes)" >> "$GITHUB_OUTPUT"
287+ - name : Generate protected CI evidence manifest
288+ working-directory : mesh
289+ run : |
290+ node scripts/protected-evidence-manifest.mjs \
291+ --source-sha "${{ github.sha }}" \
292+ --tree-hash "$(git rev-parse HEAD^{tree})" \
293+ --workflow-name CI \
294+ --run-id "${{ github.run_id }}" \
295+ --run-attempt "${{ github.run_attempt }}" \
296+ --workflow-uri "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
297+ --payload-path release/ci-run-results.json \
298+ --payload-name ci-r0-payload-${{ github.sha }} \
299+ --payload-uri "${{ steps.payload.outputs.artifact-url }}" \
300+ --payload-digest "${{ steps.payload.outputs.artifact-digest }}" \
301+ --payload-size "${{ steps.payload-metadata.outputs.size }}" \
302+ --command "matrix-rust + legacy-rust + check-frontend protected jobs" \
303+ --build-mode matrix-voice \
304+ --features matrix-voice,legacy-p2p \
305+ --retention-days 90 \
306+ --output release/ci-protected-evidence-manifest.json
307+ - name : Upload protected CI evidence manifest
308+ uses : actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
309+ with :
310+ name : ci-protected-evidence-${{ github.sha }}
311+ path : mesh/release/ci-protected-evidence-manifest.json
312+ if-no-files-found : error
313+ retention-days : 90
0 commit comments