From da80fcc35eb5b4ad0175c0f1695437cd60d4c042 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 1 Aug 2026 16:05:06 +0000 Subject: [PATCH 1/8] build(deps): bump the python-deps group across 1 directory with 3 updates Bumps the python-deps group with 3 updates in the / directory: [fastapi](https://github.com/fastapi/fastapi), [prometheus-client](https://github.com/prometheus/client_python) and [zizmor](https://github.com/zizmorcore/zizmor). Updates `fastapi` from 0.139.2 to 0.140.4 - [Release notes](https://github.com/fastapi/fastapi/releases) - [Commits](https://github.com/fastapi/fastapi/compare/0.139.2...0.140.4) Updates `prometheus-client` from 0.25.0 to 0.26.0 - [Release notes](https://github.com/prometheus/client_python/releases) - [Commits](https://github.com/prometheus/client_python/compare/v0.25.0...v0.26.0) Updates `zizmor` from 1.5.2 to 1.28.0 - [Release notes](https://github.com/zizmorcore/zizmor/releases) - [Changelog](https://github.com/zizmorcore/zizmor/blob/main/docs/release-notes.md) - [Commits](https://github.com/zizmorcore/zizmor/compare/v1.5.2...v1.28.0) --- updated-dependencies: - dependency-name: fastapi dependency-version: 0.140.4 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: python-deps - dependency-name: prometheus-client dependency-version: 0.26.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: python-deps - dependency-name: zizmor dependency-version: 1.28.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: python-deps ... Signed-off-by: dependabot[bot] --- pyproject.toml | 2 +- uv.lock | 42 +++++++++++++++++++++--------------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 847114b1..ea18189a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -263,7 +263,7 @@ messagefoundry-tray = "messagefoundry.tray.__main__:main" ci-scanners = [ "bandit==1.9.4", "pip-audit==2.10.1", - "zizmor==1.5.2", + "zizmor==1.28.0", ] # The ADVISORY measurement tools (quality-advisory.yml). Exact where something PARSES the tool's # output, a floor where nothing does: diff --git a/uv.lock b/uv.lock index 8949b977..89351632 100644 --- a/uv.lock +++ b/uv.lock @@ -553,7 +553,7 @@ wheels = [ [[package]] name = "fastapi" -version = "0.139.2" +version = "0.140.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-doc" }, @@ -562,9 +562,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/cd/95/d3f0ae10836324a2eab98a52b61210ac609f08200bf4bb0dc8132d32f78a/fastapi-0.139.2.tar.gz", hash = "sha256:333145a6891e9b5b3cfceb69baf817e8240cde4d4588ae5a10bf56ffacb6255e", size = 423428, upload-time = "2026-07-16T15:06:17.912Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/24/da8da082a850c9732dd5a5b3ccdfe51844750e42f83c430b0d8e241eab2e/fastapi-0.140.4.tar.gz", hash = "sha256:4a040c5d047486a62c497eb6e926a6d6b281efb7f99b8b50288489ba1fa0a468", size = 421514, upload-time = "2026-07-27T15:46:48.011Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5f/c7/cb03251d9dfb177246a9809a76f189d21df32dbd4a845951881d11323b7f/fastapi-0.139.2-py3-none-any.whl", hash = "sha256:b9ad015a835173d59865e2f5d8296fbc2b317bf56a2ba1a5bfbdd03de2fd4b1c", size = 130234, upload-time = "2026-07-16T15:06:19.557Z" }, + { url = "https://files.pythonhosted.org/packages/65/77/2915c0cc8b602f3d611294920171c67ce396b43cda5fa63f3e4b465d635e/fastapi-0.140.4-py3-none-any.whl", hash = "sha256:6a1f8ec2f01ae47c96dc991d49660ce4f31f50ed0d7c9df80c5e57037bfe1240", size = 130958, upload-time = "2026-07-27T15:46:49.175Z" }, ] [[package]] @@ -1126,7 +1126,7 @@ ci-quality = [ ci-scanners = [ { name = "bandit", specifier = "==1.9.4" }, { name = "pip-audit", specifier = "==2.10.1" }, - { name = "zizmor", specifier = "==1.5.2" }, + { name = "zizmor", specifier = "==1.28.0" }, ] [[package]] @@ -1445,11 +1445,11 @@ wheels = [ [[package]] name = "prometheus-client" -version = "0.25.0" +version = "0.26.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1b/fb/d9aa83ffe43ce1f19e557c0971d04b90561b0cfd50762aafb01968285553/prometheus_client-0.25.0.tar.gz", hash = "sha256:5e373b75c31afb3c86f1a52fa1ad470c9aace18082d39ec0d2f918d11cc9ba28", size = 86035, upload-time = "2026-04-09T19:53:42.359Z" } +sdist = { url = "https://files.pythonhosted.org/packages/52/73/f1334c29c2af4cd9dba6c7817e61b611bd0215e2eb5565c6064a4de18802/prometheus_client-0.26.0.tar.gz", hash = "sha256:04a91bcf94e2cf74a44a1a874d651a2e853ed354b6e822f3b7487751465d5c2b", size = 92910, upload-time = "2026-07-24T19:36:41.893Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8d/9b/d4b1e644385499c8346fa9b622a3f030dce14cd6ef8a1871c221a17a67e7/prometheus_client-0.25.0-py3-none-any.whl", hash = "sha256:d5aec89e349a6ec230805d0df882f3807f74fd6c1a2fa86864e3c2279059fed1", size = 64154, upload-time = "2026-04-09T19:53:41.324Z" }, + { url = "https://files.pythonhosted.org/packages/eb/a3/b69efbf4143b5b9859b977770bbbabcc2796b702fa69dc40271e45cd5a56/prometheus_client-0.26.0-py3-none-any.whl", hash = "sha256:fa93d06737aa02bacd05794768508bb97d2fbee28cb3bca04eaae92f0ca953d6", size = 64494, upload-time = "2026-07-24T19:36:40.854Z" }, ] [[package]] @@ -2313,18 +2313,18 @@ wheels = [ [[package]] name = "zizmor" -version = "1.5.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c5/48/a692769e2bbb62635d55849175849bb9fec2240d0a16e16bd28d8cfe314f/zizmor-1.5.2.tar.gz", hash = "sha256:848f04c0d84b085dfb79c66951404372ebf9b3dd0c73076f1baac83db29e74e4", size = 296921, upload-time = "2025-03-23T15:01:14.821Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/59/31/f717638faf223776b239040574f67bfdeb2ef3279673c08a099a525c9f4f/zizmor-1.5.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:03b27c46d87e96a0acdf78190fbb674c174f67ded396c74dadd64d7c4ecba680", size = 4687915, upload-time = "2025-03-23T15:01:06.138Z" }, - { url = "https://files.pythonhosted.org/packages/1f/0a/0a401630e9f98b8660c20a75cfb4995245c738da90d9bc1c3cd709da8a8a/zizmor-1.5.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:a40feabc2c043aca60f9edbd35a676d97d684af5b06ed61a7752869c79b3be30", size = 4443376, upload-time = "2025-03-23T15:01:04.384Z" }, - { url = "https://files.pythonhosted.org/packages/ce/cf/91527ae1e53e3be260545630e740bd34f5dfa566b23360dea5b07d15e4e5/zizmor-1.5.2-py3-none-manylinux_2_24_aarch64.whl", hash = "sha256:9d40780b19da7901423de80ccce083a8c0d2114e0cf6432aa20d8e60d15e97f6", size = 4601870, upload-time = "2025-03-23T15:00:57.752Z" }, - { url = "https://files.pythonhosted.org/packages/b2/04/4cdec1dff48ef4bb733344568d9d6a8a82cc655581787866cf38d999001a/zizmor-1.5.2-py3-none-manylinux_2_28_armv7l.whl", hash = "sha256:df1326fe9f9ddcbe9d862a97571c848276882d0ceeee39e18fcfc9ec5c66cd7b", size = 4513121, upload-time = "2025-03-23T15:01:00.093Z" }, - { url = "https://files.pythonhosted.org/packages/dc/27/7fbb2e2ad2d33de12b15014b762d39b1529b94bcbfebf55b735e67e00bd4/zizmor-1.5.2-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:0c5f656106c430748858ae459c41c9eed09a1e01e5f42015d80c8fe34740d173", size = 4840803, upload-time = "2025-03-23T15:01:02.222Z" }, - { url = "https://files.pythonhosted.org/packages/4d/80/6061f5d37cadd185c3e921bc20b8fcf34b262cad009911c50010b7e8d3d5/zizmor-1.5.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:5e18b06af4208624ef707e7859b07539870ca26b74a89537e1a6bfba2e44fc9a", size = 4590530, upload-time = "2025-03-23T15:01:08.435Z" }, - { url = "https://files.pythonhosted.org/packages/35/61/777a1ac136d8f256d94f2f269baeb11a6874a9241953fd6694fd4eb5751c/zizmor-1.5.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:506b355c693d40df01bdf26fd1dfcb41801af7b8c51767d4159efdc2655965c4", size = 4525617, upload-time = "2025-03-23T15:01:10.738Z" }, - { url = "https://files.pythonhosted.org/packages/09/46/8ba5dc116afd6105774ba527d66e7ecf635b2fdf56daddd18ef2933201e6/zizmor-1.5.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:8c65b4dbc9690d3f0f5d9756ae0b5ca8d3dfb4f806d82a5195836a3b613ae996", size = 4914859, upload-time = "2025-03-23T15:01:12.911Z" }, - { url = "https://files.pythonhosted.org/packages/df/0e/9fd2a2e3bbc904878c74a4270aef61be8564f88d68a3dc6ebdc3e0ea2b81/zizmor-1.5.2-py3-none-win32.whl", hash = "sha256:dcef697a88983e7ce6948df1603e2325e2cf5c523828af94615e6c432fa8d98a", size = 3939633, upload-time = "2025-03-23T15:01:18.196Z" }, - { url = "https://files.pythonhosted.org/packages/94/60/837501b8fc475086f5f26c72fa77513cedb5f761744bca809fdc2ee68e6a/zizmor-1.5.2-py3-none-win_amd64.whl", hash = "sha256:86395dd985ed6bf9acffea8a900b30d8d4dd4c9e20421f16f2db7ad92299e24e", size = 4435978, upload-time = "2025-03-23T15:01:16.284Z" }, +version = "1.28.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/64/92/6b58872ac1184a441037bdc05c658a3900f49401b25f6e834a268ef6ff52/zizmor-1.28.0.tar.gz", hash = "sha256:6d5a300b80bf4c12e9cbe78ffd3874ec3f94b65bea78c994ec18157e2846ece0", size = 550169, upload-time = "2026-07-21T22:16:27.361Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e8/48/a725a1c34e5565eeeb4e4a93c59662f206e5156f2029627c66b2373edf55/zizmor-1.28.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:149dba59a8bd2897960ee54c40ae8b5801a71293bad71c8d2913c74ab66a294c", size = 8909502, upload-time = "2026-07-21T22:16:07.47Z" }, + { url = "https://files.pythonhosted.org/packages/20/92/ba6d0eb2b336b4c4826bb0c9ed23c3239d46d71d8c1ddd2d395efeff7f52/zizmor-1.28.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:0949f57a6d20deeb9c509705afce8de233c166475e25be305985a1fe553c6e0d", size = 8520554, upload-time = "2026-07-21T22:16:09.587Z" }, + { url = "https://files.pythonhosted.org/packages/4f/07/69aba8157056fc0949cbdc787d8437813961e204a117c629d34afc827d6d/zizmor-1.28.0-py3-none-manylinux_2_24_aarch64.whl", hash = "sha256:9819f91f0ef486e4af98a6aacfed23c6b4067fabcecb88d49231228a3d43f821", size = 8759226, upload-time = "2026-07-21T22:16:11.627Z" }, + { url = "https://files.pythonhosted.org/packages/69/33/b65717a3ca4573611f47612e67be5458ff700e857f49f759741fa67b0519/zizmor-1.28.0-py3-none-manylinux_2_28_armv7l.whl", hash = "sha256:354e6cb98a15a88593a6f7ac6236b092b83a2aad5c4768ee750f9b3262f668d9", size = 8382005, upload-time = "2026-07-21T22:16:13.896Z" }, + { url = "https://files.pythonhosted.org/packages/5b/b4/f823bd2a1ba6dc432fdcbd249d4c442ce79bd137d34d986fce5c181f2800/zizmor-1.28.0-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:ae2cab67ce713e760e0d1b61ad749d374693ea2b310337aab11cd446748267f3", size = 9175601, upload-time = "2026-07-21T22:16:16.177Z" }, + { url = "https://files.pythonhosted.org/packages/f3/75/adad17b0320eb3bc9ed797019fccf69a809affdf5ba9402bdc8b910957e1/zizmor-1.28.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:7b00018cf2cc948c3b3e010c1a1f30fdc001f0d062640469f17e0ef006e74eb7", size = 8792861, upload-time = "2026-07-21T22:16:18.035Z" }, + { url = "https://files.pythonhosted.org/packages/1a/3d/4d5583f24730f404c104eacf8aca4ca5a3d4c480e9d3cfe3eadd93351fd6/zizmor-1.28.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:6897f02b0d02fd709f5ebc13cd37d97ad464219e0ba86a03f6d86f7777b7b102", size = 8343070, upload-time = "2026-07-21T22:16:20.092Z" }, + { url = "https://files.pythonhosted.org/packages/97/e2/4521e6dd56bc0d44eefb177794e261925c5cd00ab647b17e5513bddcb985/zizmor-1.28.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:ef69d198dcf6835c9b6eea8673cbc5c36f10b3f1b98b51d28266b7e01c3704d4", size = 9262222, upload-time = "2026-07-21T22:16:21.89Z" }, + { url = "https://files.pythonhosted.org/packages/a2/96/5d841d197c821921cb8243352c610ca2505a86871c10f81efe4da190d24c/zizmor-1.28.0-py3-none-win32.whl", hash = "sha256:833c360ba5a9c74ca45007b8c79939826fca0c5ed65144fa08f63a7009cef096", size = 7541161, upload-time = "2026-07-21T22:16:23.965Z" }, + { url = "https://files.pythonhosted.org/packages/b1/f5/3f4591746e5a9c7e8efc2e9e02aa43e1aa0957fe33cae64ce386c74b882e/zizmor-1.28.0-py3-none-win_amd64.whl", hash = "sha256:c93b30d211b0b0c38905a8803cc2653fff37de03eb77105302a02f709773bd4a", size = 8619340, upload-time = "2026-07-21T22:16:25.6Z" }, ] From e78c05c9ef6fec1e29674a3a8dace2d0f000059f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 1 Aug 2026 16:05:36 +0000 Subject: [PATCH 2/8] chore(deps): resync exported lock files (DEP-1) --- ci/locks/ci-scanners.lock | 24 ++++++++++++------------ constraints.lock | 4 ++-- docker/locks/requirements-core.lock | 12 ++++++------ docker/locks/requirements-sqlserver.lock | 12 ++++++------ requirements.lock | 12 ++++++------ 5 files changed, 32 insertions(+), 32 deletions(-) diff --git a/ci/locks/ci-scanners.lock b/ci/locks/ci-scanners.lock index 471ed1fb..06c3474f 100644 --- a/ci/locks/ci-scanners.lock +++ b/ci/locks/ci-scanners.lock @@ -220,15 +220,15 @@ urllib3==2.7.0 \ --hash=sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c \ --hash=sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897 # via requests -zizmor==1.5.2 \ - --hash=sha256:03b27c46d87e96a0acdf78190fbb674c174f67ded396c74dadd64d7c4ecba680 \ - --hash=sha256:0c5f656106c430748858ae459c41c9eed09a1e01e5f42015d80c8fe34740d173 \ - --hash=sha256:506b355c693d40df01bdf26fd1dfcb41801af7b8c51767d4159efdc2655965c4 \ - --hash=sha256:5e18b06af4208624ef707e7859b07539870ca26b74a89537e1a6bfba2e44fc9a \ - --hash=sha256:848f04c0d84b085dfb79c66951404372ebf9b3dd0c73076f1baac83db29e74e4 \ - --hash=sha256:86395dd985ed6bf9acffea8a900b30d8d4dd4c9e20421f16f2db7ad92299e24e \ - --hash=sha256:8c65b4dbc9690d3f0f5d9756ae0b5ca8d3dfb4f806d82a5195836a3b613ae996 \ - --hash=sha256:9d40780b19da7901423de80ccce083a8c0d2114e0cf6432aa20d8e60d15e97f6 \ - --hash=sha256:a40feabc2c043aca60f9edbd35a676d97d684af5b06ed61a7752869c79b3be30 \ - --hash=sha256:dcef697a88983e7ce6948df1603e2325e2cf5c523828af94615e6c432fa8d98a \ - --hash=sha256:df1326fe9f9ddcbe9d862a97571c848276882d0ceeee39e18fcfc9ec5c66cd7b +zizmor==1.28.0 \ + --hash=sha256:0949f57a6d20deeb9c509705afce8de233c166475e25be305985a1fe553c6e0d \ + --hash=sha256:149dba59a8bd2897960ee54c40ae8b5801a71293bad71c8d2913c74ab66a294c \ + --hash=sha256:354e6cb98a15a88593a6f7ac6236b092b83a2aad5c4768ee750f9b3262f668d9 \ + --hash=sha256:6897f02b0d02fd709f5ebc13cd37d97ad464219e0ba86a03f6d86f7777b7b102 \ + --hash=sha256:6d5a300b80bf4c12e9cbe78ffd3874ec3f94b65bea78c994ec18157e2846ece0 \ + --hash=sha256:7b00018cf2cc948c3b3e010c1a1f30fdc001f0d062640469f17e0ef006e74eb7 \ + --hash=sha256:833c360ba5a9c74ca45007b8c79939826fca0c5ed65144fa08f63a7009cef096 \ + --hash=sha256:9819f91f0ef486e4af98a6aacfed23c6b4067fabcecb88d49231228a3d43f821 \ + --hash=sha256:ae2cab67ce713e760e0d1b61ad749d374693ea2b310337aab11cd446748267f3 \ + --hash=sha256:c93b30d211b0b0c38905a8803cc2653fff37de03eb77105302a02f709773bd4a \ + --hash=sha256:ef69d198dcf6835c9b6eea8673cbc5c36f10b3f1b98b51d28266b7e01c3704d4 diff --git a/constraints.lock b/constraints.lock index 457dbc6d..d68ee180 100644 --- a/constraints.lock +++ b/constraints.lock @@ -63,7 +63,7 @@ defusedxml==0.7.1 # pyx12 elementpath==5.1.3 # via xmlschema -fastapi==0.139.2 +fastapi==0.140.4 # via messagefoundry fhir-core==1.1.9 # via fhir-resources @@ -152,7 +152,7 @@ pathspec==1.1.1 # via mypy pluggy==1.6.0 # via pytest -prometheus-client==0.25.0 +prometheus-client==0.26.0 # via messagefoundry protobuf==6.33.6 # via diff --git a/docker/locks/requirements-core.lock b/docker/locks/requirements-core.lock index c59fc7a0..d1c53f74 100644 --- a/docker/locks/requirements-core.lock +++ b/docker/locks/requirements-core.lock @@ -139,9 +139,9 @@ defusedxml==0.7.1 \ --hash=sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69 \ --hash=sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61 # via messagefoundry -fastapi==0.139.2 \ - --hash=sha256:333145a6891e9b5b3cfceb69baf817e8240cde4d4588ae5a10bf56ffacb6255e \ - --hash=sha256:b9ad015a835173d59865e2f5d8296fbc2b317bf56a2ba1a5bfbdd03de2fd4b1c +fastapi==0.140.4 \ + --hash=sha256:4a040c5d047486a62c497eb6e926a6d6b281efb7f99b8b50288489ba1fa0a468 \ + --hash=sha256:6a1f8ec2f01ae47c96dc991d49660ce4f31f50ed0d7c9df80c5e57037bfe1240 # via messagefoundry h11==0.16.0 \ --hash=sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1 \ @@ -192,9 +192,9 @@ ldap3==2.9.1 \ --hash=sha256:5869596fc4948797020d3f03b7939da938778a0f9e2009f7a072ccf92b8e8d70 \ --hash=sha256:f3e7fc4718e3f09dda568b57100095e0ce58633bcabbed8667ce3f8fbaa4229f # via messagefoundry -prometheus-client==0.25.0 \ - --hash=sha256:5e373b75c31afb3c86f1a52fa1ad470c9aace18082d39ec0d2f918d11cc9ba28 \ - --hash=sha256:d5aec89e349a6ec230805d0df882f3807f74fd6c1a2fa86864e3c2279059fed1 +prometheus-client==0.26.0 \ + --hash=sha256:04a91bcf94e2cf74a44a1a874d651a2e853ed354b6e822f3b7487751465d5c2b \ + --hash=sha256:fa93d06737aa02bacd05794768508bb97d2fbee28cb3bca04eaae92f0ca953d6 # via messagefoundry psutil==7.2.2 \ --hash=sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372 \ diff --git a/docker/locks/requirements-sqlserver.lock b/docker/locks/requirements-sqlserver.lock index ad3e94e2..2e0855d7 100644 --- a/docker/locks/requirements-sqlserver.lock +++ b/docker/locks/requirements-sqlserver.lock @@ -143,9 +143,9 @@ defusedxml==0.7.1 \ --hash=sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69 \ --hash=sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61 # via messagefoundry -fastapi==0.139.2 \ - --hash=sha256:333145a6891e9b5b3cfceb69baf817e8240cde4d4588ae5a10bf56ffacb6255e \ - --hash=sha256:b9ad015a835173d59865e2f5d8296fbc2b317bf56a2ba1a5bfbdd03de2fd4b1c +fastapi==0.140.4 \ + --hash=sha256:4a040c5d047486a62c497eb6e926a6d6b281efb7f99b8b50288489ba1fa0a468 \ + --hash=sha256:6a1f8ec2f01ae47c96dc991d49660ce4f31f50ed0d7c9df80c5e57037bfe1240 # via messagefoundry h11==0.16.0 \ --hash=sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1 \ @@ -196,9 +196,9 @@ ldap3==2.9.1 \ --hash=sha256:5869596fc4948797020d3f03b7939da938778a0f9e2009f7a072ccf92b8e8d70 \ --hash=sha256:f3e7fc4718e3f09dda568b57100095e0ce58633bcabbed8667ce3f8fbaa4229f # via messagefoundry -prometheus-client==0.25.0 \ - --hash=sha256:5e373b75c31afb3c86f1a52fa1ad470c9aace18082d39ec0d2f918d11cc9ba28 \ - --hash=sha256:d5aec89e349a6ec230805d0df882f3807f74fd6c1a2fa86864e3c2279059fed1 +prometheus-client==0.26.0 \ + --hash=sha256:04a91bcf94e2cf74a44a1a874d651a2e853ed354b6e822f3b7487751465d5c2b \ + --hash=sha256:fa93d06737aa02bacd05794768508bb97d2fbee28cb3bca04eaae92f0ca953d6 # via messagefoundry psutil==7.2.2 \ --hash=sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372 \ diff --git a/requirements.lock b/requirements.lock index bdd8b27f..5dc2b8f1 100644 --- a/requirements.lock +++ b/requirements.lock @@ -317,9 +317,9 @@ elementpath==5.1.3 \ --hash=sha256:35e98cc2e26332305a49b32eaaebfb7289d1963c88d3989ff5ccb02c46809820 \ --hash=sha256:c46f5e0e36c149b892308843e1e394bdee17ceafbc18cfa39250403dd8475a4e # via xmlschema -fastapi==0.139.2 \ - --hash=sha256:333145a6891e9b5b3cfceb69baf817e8240cde4d4588ae5a10bf56ffacb6255e \ - --hash=sha256:b9ad015a835173d59865e2f5d8296fbc2b317bf56a2ba1a5bfbdd03de2fd4b1c +fastapi==0.140.4 \ + --hash=sha256:4a040c5d047486a62c497eb6e926a6d6b281efb7f99b8b50288489ba1fa0a468 \ + --hash=sha256:6a1f8ec2f01ae47c96dc991d49660ce4f31f50ed0d7c9df80c5e57037bfe1240 # via messagefoundry fhir-core==1.1.9 \ --hash=sha256:61f23a711199d8d74390fd473cc5ddf75a1f4def97fd8e9f59a28bc9d5222261 \ @@ -570,9 +570,9 @@ pluggy==1.6.0 \ --hash=sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3 \ --hash=sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 # via pytest -prometheus-client==0.25.0 \ - --hash=sha256:5e373b75c31afb3c86f1a52fa1ad470c9aace18082d39ec0d2f918d11cc9ba28 \ - --hash=sha256:d5aec89e349a6ec230805d0df882f3807f74fd6c1a2fa86864e3c2279059fed1 +prometheus-client==0.26.0 \ + --hash=sha256:04a91bcf94e2cf74a44a1a874d651a2e853ed354b6e822f3b7487751465d5c2b \ + --hash=sha256:fa93d06737aa02bacd05794768508bb97d2fbee28cb3bca04eaae92f0ca953d6 # via messagefoundry protobuf==6.33.6 \ --hash=sha256:0cd27b587afca21b7cfa59a74dcbd48a50f0a6400cfb59391340ad729d91d326 \ From a9b03eb2a310bca3abf2d7c1679b571d2a4b63c8 Mon Sep 17 00:00:00 2001 From: wshallwshall Date: Sat, 1 Aug 2026 15:18:32 -0500 Subject: [PATCH 3/8] =?UTF-8?q?fix(ci):=20label=20the=20setup-node=20pins?= =?UTF-8?q?=20v7.0.0=20=E2=80=94=20the=20SHA=20has=20been=20v7=20since=202?= =?UTF-8?q?026-07-26?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three pins read `actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6` while that SHA is what `refs/tags/v7` AND `refs/tags/v7.0.0` point at — verified against the upstream refs API, not inferred from the lint. So the repo has been running setup-node v7 for a week with a comment asserting v6. This RATIFIES a major already in force; it is not a cosmetic label fix. v7 is green on both `ide build` legs and on the required `npm-audit` job, and reverting to the v6 line would be worse, not safer: v6 carries fast-xml-parser 5.9.3, which sits inside GHSA-8r6m-32jq-jx6q, while v7.0.0's 5.7.2 is in no open advisory range. The SHA is unchanged. Only the comment moves, and all three move together — one Dependabot change introduced them and they must not drift apart. Surfaced by zizmor 1.28.0's ref-version-mismatch audit, which could not run before #121 put ci/locks/ci-scanners.lock in the zizmor paths filter. --- .github/workflows/ci.yml | 2 +- .github/workflows/security.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c28844ef..80ca90b9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -298,7 +298,7 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Set up Node - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: "24" cache: npm diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index e8f06bf8..8e205483 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -156,7 +156,7 @@ jobs: steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Set up Node - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: "24" - name: Audit the locked npm dependencies (install-free) @@ -186,7 +186,7 @@ jobs: with: python-version: "3.14" - name: Set up Node - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: "24" - name: Generate the Python engine SBOM (license-complete, hash-locked core runtime) From 0fdc326eac3f966ee44bad896b7fa63f87a57b9a Mon Sep 17 00:00:00 2001 From: wshallwshall Date: Sat, 1 Aug 2026 15:22:10 -0500 Subject: [PATCH 4/8] ci(zizmor): retire the dead ignore entry and the claims that rotted with it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The config header calls every entry "a REVIEWED, justified non-finding", which makes a stale one worse than noise — it reads as a reviewed risk that is actually unexamined. Five had rotted, each verified against the tree rather than taken from the lint: * `release-sync-check.yml` is ignored under artipacked, but that workflow was deleted in 59fbc938 (2026-07-26). An entry naming a file that cannot produce a finding is dead config presenting as coverage. * "The jobs below do not push" — `dependabot-lock-resync.yml` is in that list and pushes at line 160. The carve-out two lines below already says so. * "release.yml sets persist-credentials: false on both checkouts" — it has three (73, 371, 498), all false. The claim is right and the count is a liability, so the count goes. * "cla.yml ... does check out" — cla.yml has zero checkouts. The comparison it was drawing still holds on a different axis (third-party code vs none), so that is what it now says. * "See the SECURITY note in cla.yml" — cla.yml contains no such note. A security justification whose only citation does not resolve. Adds tests/test_zizmor_config_hygiene.py so the first one cannot recur: every ignore entry must name a live workflow. Validated both directions — it passes on this tree and fails when the deleted entry is put back. It also prints what it scanned, so a run that silently covered nothing is distinguishable from a pass. --- .github/zizmor.yml | 16 +++++++----- tests/test_zizmor_config_hygiene.py | 40 +++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 tests/test_zizmor_config_hygiene.py diff --git a/.github/zizmor.yml b/.github/zizmor.yml index 11b76936..122812d5 100644 --- a/.github/zizmor.yml +++ b/.github/zizmor.yml @@ -10,7 +10,8 @@ rules: # A CLA assistant REQUIRES pull_request_target to record signatures + comment on fork PRs. This # workflow never checks out untrusted PR code, pins the third-party action by SHA, and gates on the # immutable comment body / event name — so the usual pull_request_target risk (running attacker - # code with a write token) does not apply. See the SECURITY note in cla.yml. + # code with a write token) does not apply. The action is pinned at ca4a40a7d100 (v2.6.1); its + # archived-upstream status is adjudicated under archived-uses below. - cla.yml # A notice that a SCHEDULED run failed can only be written by something observing that run AFTER # it finishes — no other trigger sees another workflow's conclusion, so `workflow_run` is not a @@ -22,7 +23,9 @@ rules: # tests/test_nightly_notice.py rather than merely asserted here: # * NO checkout, and no third-party actions at all — `test_it_pulls_in_no_third_party_actions` # fails if a `uses:` ever appears. Nothing from the triggering ref is fetched, let alone run. - # That is a STRONGER claim than cla.yml's above, which does check out. + # That is a STRONGER claim than cla.yml's above: cla.yml runs a third-party action with a + # write token — SHA-pinned, so it cannot change under us, but still third-party code — + # whereas this job runs no third-party code at all. # * It only reacts to `workflow_run.event == 'schedule'` # (`test_it_only_reacts_to_scheduled_runs`), so a PR — including a fork PR — has no path to # the job at all. @@ -36,16 +39,15 @@ rules: artipacked: ignore: # artipacked flags a checkout that persists the token's git credential — a risk only if that - # credential can leak into an uploaded artifact. The jobs below do not push and never upload the - # repo/.git tree, so the persisted credential is inert noise here. + # credential can leak into an uploaded artifact. The jobs below never upload the repo/.git tree, + # so the persisted credential is inert noise here. # - # NOT suppressed (fixed at the source instead): release.yml sets persist-credentials: false on both - # checkouts because it DOES upload build artifacts. dependabot-lock-resync.yml persists a + # NOT suppressed (fixed at the source instead): release.yml's checkouts set persist-credentials: + # false, because it DOES upload build artifacts. dependabot-lock-resync.yml persists a # narrowly-scoped App token ON PURPOSE to push the resynced locks (documented inline) and is listed # here for that reason. - benchmark.yml - ci.yml - dependabot-lock-resync.yml - - release-sync-check.yml - security.yml - vuln-metrics.yml diff --git a/tests/test_zizmor_config_hygiene.py b/tests/test_zizmor_config_hygiene.py new file mode 100644 index 00000000..b7286288 --- /dev/null +++ b/tests/test_zizmor_config_hygiene.py @@ -0,0 +1,40 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +# Copyright (C) 2026 MessageFoundry Organization and contributors +"""Every zizmor suppression must name a workflow that still exists. + +``.github/zizmor.yml`` was asserted by nothing, so its ``release-sync-check.yml`` entry survived that +workflow's deletion (59fbc938, 2026-07-26) and sat there reading as coverage. zizmor's ignore entries +are BASE filenames (``filename.yml[:line[:column]]``) resolved against the scan target, and +zizmor.yml's job runs ``zizmor .github/workflows`` — so the ignore namespace is exactly that +directory's contents, and an entry naming anything else can never match. + +A dead entry is worse than noise: this file's header calls every entry "a REVIEWED, justified +non-finding", so a name that cannot match reads as a reviewed risk that is actually unexamined. +""" + +from __future__ import annotations + +from tests._workflow_contexts import ROOT, WORKFLOWS + +_CONFIG = ROOT / ".github" / "zizmor.yml" + + +def test_every_zizmor_ignore_names_a_live_workflow() -> None: + import yaml + + assert _CONFIG.is_file(), f"{_CONFIG} is missing — this guard cannot pass vacuously" + config = yaml.safe_load(_CONFIG.read_text(encoding="utf-8")) or {} + scanned: list[str] = [] + for audit, body in (config.get("rules") or {}).items(): + for entry in (body or {}).get("ignore") or []: + basename = str(entry).split(":", 1)[0] + scanned.append(f"{audit} -> {entry}") + assert (WORKFLOWS / basename).is_file(), ( + f"{audit}.ignore names {basename}, which is not in .github/workflows/ — the " + "workflow was deleted or renamed and its suppression must go with it" + ) + # Print what was covered: a gate that silently scanned nothing looks identical to a passing one. + print(f"scanned {len(scanned)} zizmor ignore entries: {scanned}") + assert scanned, ( + "parsed zero ignore entries — the config shape changed and this guard went blind" + ) From def4533615557e65f0b63b9d4fbbd9d56ccd3f70 Mon Sep 17 00:00:00 2001 From: wshallwshall Date: Sat, 1 Aug 2026 15:23:44 -0500 Subject: [PATCH 5/8] ci(zizmor): record bot-conditions on the resync gate as a justified non-finding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit zizmor 1.28.0 reports `github.triggering_actor == 'dependabot[bot]'` at dependabot-lock-resync.yml:76 as a spoofable bot actor check. The observation is correct and the gate is still FAIL-CLOSED, because that expression is the second half of a conjunction: github.event.pull_request.user.login == 'dependabot[bot]' && github.triggering_actor == 'dependabot[bot]' Clause 1 is the immutable PR author — the exact context this audit recommends as the replacement. A conjunction only narrows, so spoofing the actor can make the job SKIP, never run, and skipping is safe: DEP-1 lock sync is independently enforced by security.yml's pip-audit job, a required context on an unfiltered trigger. zizmor itself agrees enough to report at MEDIUM confidence, treating `And` as non-dominating. So this is suppressed, line-anchored, not fixed — and PR #121's description needs no correction: it claimed a human push makes the job skip, which is the fail-closed direction, while this audit is about a check wrongly passing. Two things the suppression does NOT rely on prose for: * tests/test_dep1_lock_resync_lockstep.py now pins the premise — clause 1 present, conjoined, no `||`. Validated by mutation: flipping `&&` to `||` and deleting clause 1 each turn it red. Without this the suppression would be an assertion about a shape nothing enforces. * The comment records that zizmor's auto-fix for this audit is classified SAFE, so a bare `zizmor --fix` would apply it silently — substituting clause 1 for clause 2, collapsing the condition to `A && A` and deleting the self-trigger skip, with every check still green. --- .github/zizmor.yml | 30 +++++++++++++++++++++++++ tests/test_dep1_lock_resync_lockstep.py | 21 +++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/.github/zizmor.yml b/.github/zizmor.yml index 122812d5..3779f1b9 100644 --- a/.github/zizmor.yml +++ b/.github/zizmor.yml @@ -51,3 +51,33 @@ rules: - dependabot-lock-resync.yml - security.yml - vuln-metrics.yml + + bot-conditions: + ignore: + # zizmor flags `github.triggering_actor == 'dependabot[bot]'` in the resync job's `if:`, because an + # actor context reflects the LAST actor on the run, not the PR's author. True — and it is why that + # expression is the SECOND half of a conjunction and never the control. The control is the FIRST + # half, `github.event.pull_request.user.login == 'dependabot[bot]'`: the immutable PR author, and + # the exact replacement this audit recommends. A conjunction only NARROWS, so a spoofed actor can + # make this job SKIP, never run. zizmor agrees — it treats `And` as non-dominating and reports this + # at MEDIUM confidence for that reason. + # + # Skipping is safe by design: DEP-1 lock/export sync is independently enforced by security.yml's + # `pip-audit` job, step "Check the lockfile is in sync with pyproject (DEP-1)", which + # `git diff --exit-code`s the re-exports on an unfiltered pull_request trigger and is a REQUIRED + # context. The actor half is an operational self-trigger skip: this job's own App-token push fires + # a `synchronize` whose triggering actor is mefor-lock-resync[bot], a run that sees no Dependabot + # secrets. See the SECURITY MODEL block and the numbered note above that `if:`. + # + # DO NOT TAKE ZIZMOR'S AUTO-FIX. It is classified SAFE, so a bare `zizmor --fix` applies it + # silently: for a `pull_request` trigger it substitutes `github.event.pull_request.user.login`, + # collapsing the conjunction into `A && A` and deleting the self-trigger skip. Nothing in CI would + # catch that — every test and required check stays green while the skip is gone. + # + # The premise this suppression rests on — clause 1 present, conjoined, no `||` — is PINNED by + # tests/test_dep1_lock_resync_lockstep.py rather than merely asserted here. Line-anchored on + # purpose: a file-level entry would also swallow a future actor check added to this file as a SOLE + # gate, which is the shape that IS exploitable. Accepted residual: an in-place rewrite that keeps + # the line count would not re-fire the finding — that is what the test is for. If the line moves, + # RE-ANCHOR it; do not broaden it to the file. + - dependabot-lock-resync.yml:76 diff --git a/tests/test_dep1_lock_resync_lockstep.py b/tests/test_dep1_lock_resync_lockstep.py index 6b0240c8..7bd961db 100644 --- a/tests/test_dep1_lock_resync_lockstep.py +++ b/tests/test_dep1_lock_resync_lockstep.py @@ -20,6 +20,8 @@ import re from pathlib import Path +from tests._workflow_contexts import load_workflow + _WORKFLOWS = Path(__file__).resolve().parent.parent / ".github" / "workflows" _GATE = _WORKFLOWS / "security.yml" _RESYNC = _WORKFLOWS / "dependabot-lock-resync.yml" @@ -98,3 +100,22 @@ def test_constraints_lock_is_in_the_set() -> None: "dependabot-lock-resync.yml stopped re-exporting constraints.lock — every Dependabot uv PR " "will be red with no bot-reachable path to green (see this module's docstring)" ) + + +def test_the_resync_gate_keeps_its_immutable_author_conjunct() -> None: + """The zizmor ``bot-conditions`` suppression is sound only while clause 1 is present. + + zizmor flags ``github.triggering_actor`` in this job's ``if:``. That is safe ONLY because it is + conjoined with the immutable PR-author check: a conjunction can only narrow, so a spoofed actor + makes the job skip, never run. Drop clause 1 -- or turn the ``&&`` into ``||`` -- and the residual + actor check becomes a SOLE gate, the exploitable shape. ``.github/zizmor.yml``'s bot-conditions + entry asserts that shape is absent; this is what makes the assertion true rather than asserted. + """ + condition = load_workflow("dependabot-lock-resync.yml")["jobs"]["resync"]["if"] + assert "github.event.pull_request.user.login == 'dependabot[bot]'" in condition, ( + "the immutable author gate is gone; the zizmor bot-conditions suppression is now unsound" + ) + assert "&&" in condition, "the author gate must CONJOIN the actor check, not replace it" + assert "||" not in condition, ( + "a disjunction lets the spoofable actor check alone open the job — the dominating shape" + ) From 3787419570137232072996ebac162ad8e22d332a Mon Sep 17 00:00:00 2001 From: wshallwshall Date: Sat, 1 Aug 2026 15:26:00 -0500 Subject: [PATCH 6/8] ci(zizmor): accept the archived CLA action as a dated residual (ADR 0034) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit zizmor 1.28.0's archived-uses audit is right: contributor-assistant/github-action is archived upstream (API archived: true, last push 2026-03-23) and v2.6.1 is the final release. Our pin equals that tag's commit exactly, so there is no later patch to move to. Recorded as an accepted residual, not waved away as a false positive. The SHA pin closes tampering — a bundled JS action's SHA fully determines the bytes that run — but not the axis the audit names: a flaw already at that SHA will never be fixed. Not replaced now, deliberately. `cla` is a required status context AND is the job's own conclusion, so a broken step blocks every contribution; and because pull_request_target/issue_comment workflows run only from the default branch, a replacement cannot be exercised on the PR that makes it — it would land on main untested with approvals at 0 and auto-merge armed. The forcing function is not this lint: action.yml declares `runs.using: node20` at the pin and at the archived HEAD, so an archived repo can never re-declare node24 and GitHub's fall-2026 Node20 removal decides it. The suppression is dated and says to re-check before then, rather than being open-ended. The ADR amendment records a contingency candidate with its provenance checked rather than asserted: iainmcgin/cla-github-action is real, Apache-2.0, unarchived — and its v3.2.0 is an ANNOTATED tag, so the ref resolves to a tag object, not the commit. The commit `uses:` must pin was dereferenced and confirmed. Pinning the tag-object SHA would be the same mismatch class fixed two commits ago. --- .github/zizmor.yml | 31 +++++++++++++++++ ...is-triage-policy-accepted-risk-register.md | 33 +++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/.github/zizmor.yml b/.github/zizmor.yml index 3779f1b9..6d06249d 100644 --- a/.github/zizmor.yml +++ b/.github/zizmor.yml @@ -81,3 +81,34 @@ rules: # the line count would not re-fire the finding — that is what the test is for. If the line moves, # RE-ANCHOR it; do not broaden it to the file. - dependabot-lock-resync.yml:76 + + archived-uses: + ignore: + # contributor-assistant/github-action is ARCHIVED upstream (GitHub API `archived: true`; the date + # is observed from its last push, 2026-03-23, since `archived_at` is null). v2.6.1 is both the last + # tag and the last release, and the pin ca4a40a7d1004f18d9960b404b97e5f30a505a08 equals that tag + # exactly — so there is no future patch to bump to. Recorded as an ACCEPTED RESIDUAL, not a false + # positive: the finding is true. + # + # What the SHA pin buys, and what it does not. It closes the TAMPER axis completely — a bundled JS + # action's pinned SHA fully determines the bytes that run, and a deleted or re-registered namespace + # makes this step FAIL rather than run a stranger's code. It does NOT close the axis this audit is + # about: a flaw in the code already at that SHA will never be patched. + # + # NOT REPLACED, deliberately. `cla` is a REQUIRED status context (.github/required-contexts.txt) + # and it is this JOB's own conclusion, so a broken step blocks every contribution. + # pull_request_target / issue_comment workflows run only from the DEFAULT branch, so a swap cannot + # be exercised on the PR that makes it — it lands on main untested, with approvals at 0 and + # auto-merge armed. On a step holding a write token that any GitHub user can trigger by comment, + # trading a frozen SHA-pinned bundle for a less-reviewed fork is not self-evidently a security win. + # + # WHAT WILL FORCE THE DECISION, and it is not this lint: action.yml at this SHA declares + # `runs.using: node20`, as does the archived repo's HEAD, so no upstream release can ever + # re-declare node24. GitHub removes Node20 in fall 2026. Re-check before then. Full record and the + # replacement candidate: docs/adr/0034 (amendment, 2026-08-01). + # + # Line-anchored on purpose: a file-level entry would silently swallow a SECOND archived action + # added here later. Accepted cost is drift — an inserted line re-fires the finding with no change + # in risk. Re-anchor; do not broaden. Delete this entry when the action is replaced, or if upstream + # un-archives (the audit re-checks that every run). + - cla.yml:44 diff --git a/docs/adr/0034-static-analysis-triage-policy-accepted-risk-register.md b/docs/adr/0034-static-analysis-triage-policy-accepted-risk-register.md index c96d4533..4dfc96d5 100644 --- a/docs/adr/0034-static-analysis-triage-policy-accepted-risk-register.md +++ b/docs/adr/0034-static-analysis-triage-policy-accepted-risk-register.md @@ -433,3 +433,36 @@ why export sync must be verified with `git diff` and never a raw `diff`. Fixed a **Still open, not done:** `quality-advisory.yml`'s `pipx install ruff` fallback installs *unpinned* ruff instead of failing closed, and `constraints.lock` is `sed`-scraped for a `ruff==` pin that — unlike `packaging==` — has **no PR-time canary test**. Both are recorded here; neither closes a Scorecard alert. + +## Amendment — 2026-08-01: zizmor `archived-uses` on the CLA action (accepted residual) + +Adopting zizmor 1.28.0 (from 1.5.2) turned on audits the old pin could not run. Four of the five +findings against the otherwise-unchanged tree were resolved in-tree or as justified non-findings; this +one is an accepted residual. + +* **Finding.** `warning[archived-uses]`, `.github/workflows/cla.yml:44` — + `contributor-assistant/github-action@ca4a40a7d1004f18d9960b404b97e5f30a505a08 # v2.6.1`. Upstream is + archived (API `archived: true`, `archived_at: null`; last push 2026-03-23) and v2.6.1 is the final + release. The pin equals that tag's commit exactly, so there is no later patch to move to. +* **Compensating control, and its limit.** The full-SHA pin closes tampering: a bundled JS action's SHA + fully determines the bytes that run, and a vanished namespace fails the step rather than running + someone else's code. It does not close the unpatched-code axis the audit names. +* **Why not replaced now.** `cla` is a required status context and is the job's own conclusion, so a + broken step blocks every PR. `pull_request_target`/`issue_comment` workflows run only from the default + branch, so a replacement cannot be exercised on the PR that makes it — it lands on `main` untested, + with `required_approving_review_count: 0` and auto-merge armed. +* **Hard revisit: before Node20 removal.** `action.yml` at the pin — and at the archived HEAD — declares + `runs.using: node20`. An archived repo can never re-declare node24, so GitHub's fall-2026 Node20 + removal, not this lint, forces fork-or-replace. No firm date is published; treat mid-September 2026 as + the planning date and re-check before then. +* **Contingency, verified 2026-08-01.** There is no canonical successor — the archived README directs + users to fork. The best candidate found is `iainmcgin/cla-github-action`, Apache-2.0, not archived, + last pushed 2026-06-17, 4 stars, single personal maintainer. Note v3.2.0 is an **annotated** tag whose + ref resolves to tag object `07f1588b0cee15f89a489a77704c9d45d39ec0a1`; the commit `uses:` must pin is + `0d27e5a16278d4adb6b0c4b92f08ad27b0a21dc8` (dereferenced and confirmed, not assumed). Adoption is + gated on at least: accounting for the shipped `dist/index.js` (a built bundle that is not + human-reviewable, and a source review does not prove `dist/` was built from it); confirming + `signatures/version1/cla.json` stays format-compatible; verifying the inputs `cla.yml` passes still + exist with the same semantics; a decision on `require-opener-as-author`, which defaults to true and + fails the check; and a rehearsal in a scratch repo. Land in a low-traffic window with a revert + prepared. From dcccf9d674cb3d5dc8074ccb771571b80e5bbf70 Mon Sep 17 00:00:00 2001 From: wshallwshall Date: Sat, 1 Aug 2026 18:50:19 -0500 Subject: [PATCH 7/8] ci: hand the setup-node label fix to the timeout PR to clear the collision gate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drops this branch's one-line ci.yml hunk (`# v6` -> `# v7.0.0` at :301). The change is not abandoned — the "Stuck CIs" session is carrying it in the same commit as the W22/W25 timeout raise. Why: the collision gate keys on a branch's DIFF against main, not on whether a session is actively editing. Standing down verbally did not clear it; while this branch carried any ci.yml hunk, `ci.yml` read as in-flight and the timeout edit was refused. That mattered because #130 is itself running against the 26:00 cap the timeout fix raises — so a timeout on this PR would have trapped the fix for the timeout behind a PR that died of it. Known consequence, accepted: until that commit reaches main, zizmor reports ref-version-mismatch on ci.yml:301 again — measured, 1 medium, exit 13 — so this PR's zizmor check is RED in the interim. It clears when main carries the label fix and this branch merges it. The other two sites (security.yml:159, :189) keep their fix here. Side benefit: #130 is now purely "adopt a scanner and adjudicate its findings", which is the topic separation this PR argued for. --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 80ca90b9..c28844ef 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -298,7 +298,7 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Set up Node - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6 with: node-version: "24" cache: npm From 91c412bc6e6c3f4823de56b8dc6210f0f1ba06e7 Mon Sep 17 00:00:00 2001 From: wshallwshall Date: Sat, 1 Aug 2026 18:53:59 -0500 Subject: [PATCH 8/8] Revert "ci: hand the setup-node label fix to the timeout PR to clear the collision gate" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts dcccf9d6. The handover did not complete: #131 landed the W22/W25 timeout raise but does NOT touch setup-node, so nothing else carries the `# v6` -> `# v7.0.0` label. Taking it back is now urgent rather than tidy. zizmor is deliberately NOT a required context, so a red zizmor cannot block #130 — and #130 has auto-merge armed. Left as-is, this PR would have landed zizmor 1.28.0 on main together with an unfixed ref-version-mismatch, redding the 06:00 cron that nothing alerts on (nightly-notice.yml watches CI only). That is precisely the outcome this PR exists to prevent, arriving through the PR that prevents it. The reason for handing it over is gone: the collision gate keys on a branch's diff, and #131's ci.yml edit is already committed and pushed, so re-adding this hunk cannot block it. Restores one comment. SHA unchanged; the pin has resolved to v7.0.0 since 2026-07-26. --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c28844ef..80ca90b9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -298,7 +298,7 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Set up Node - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: "24" cache: npm