From 0c5a58c4cb391b413a95c6ee06bbe195880860fc Mon Sep 17 00:00:00 2001 From: faranm-stack Date: Wed, 21 Oct 2026 19:53:23 -0400 Subject: [PATCH] fix(flowblind): package the Node 26 runtime dependencies Upgrade both public tools together, fail builds on Node loader errors, bind the current Dockerfile copies and release records, and test package recipe drift. Retain Python 3.12, historical evidence and all approval boundaries. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../flowblind-research-teammate-v2/README.md | 23 +++++++++++++++++++ ...talog-research-v2-verifier-release-v1.json | 4 ++-- ...blind-research-teammate-verification-v2.js | 2 +- ...d-catalog-research-v2-package-lock-v1.json | 12 +++++----- .../runtime/generated/data/package/README.md | 23 +++++++++++++++++++ .../data/package/flowblind-prepare.Dockerfile | 4 +++- .../package/flowblind-run-verify.Dockerfile | 4 +++- .../tests/portable-runtime.node-test.js | 13 +++++++++++ .../tools/flowblind-prepare/Dockerfile | 4 +++- ...blind-research-teammate-verification-v2.js | 2 +- ...d-catalog-research-v2-package-lock-v1.json | 12 +++++----- .../runtime/generated/data/package/README.md | 23 +++++++++++++++++++ .../data/package/flowblind-prepare.Dockerfile | 4 +++- .../package/flowblind-run-verify.Dockerfile | 4 +++- .../tools/flowblind-run-verify/Dockerfile | 4 +++- ...blind-research-teammate-verification-v2.js | 2 +- ...d-catalog-research-v2-package-lock-v1.json | 12 +++++----- .../runtime/generated/data/package/README.md | 23 +++++++++++++++++++ .../data/package/flowblind-prepare.Dockerfile | 4 +++- .../package/flowblind-run-verify.Dockerfile | 4 +++- 20 files changed, 152 insertions(+), 31 deletions(-) diff --git a/agents/flowblind-research-teammate-v2/README.md b/agents/flowblind-research-teammate-v2/README.md index c282f13a..092c4c29 100644 --- a/agents/flowblind-research-teammate-v2/README.md +++ b/agents/flowblind-research-teammate-v2/README.md @@ -90,6 +90,29 @@ decision. Preparation then also asks for approval; that is expected. The runtime requires no Git repository or repository metadata. +## Base image maintenance + +Both public tool images use the same pinned Node 26.11.1 and Python 3.12.14 +bases. The Node executable is copied into the Python final stage together +with its required `libatomic.so.1` library. `RUN node --version` makes a +missing loader dependency fail during the image build, before registration. + +A base-image update is a coordinated package change, not just a `FROM` edit: + +1. Update both tool Dockerfiles and their current canonical copies under + `runtime/generated/data/package/`. +2. Refresh the affected byte lengths and SHA-256 values in the current package + lock, the verifier's expected lock identity, and the verifier release record. +3. Keep both tool-local runtime trees byte-identical to the package runtime. + Do not rewrite retained historical manifests or enable private activation. +4. Run `npm test`, build both images for `linux/amd64`, and validate preparation + followed by execution using those exact images. Package tests check that + each outer Dockerfile matches its attested copy. + +The Python 3.12 wheel lock remains enforced with `--require-hashes`. A Python +minor-version migration needs separate wheel-lock and numerical compatibility +validation; the Node upgrade does not authorize or perform that migration. + ## Architecture The public lifecycle is deliberately split across two host-owned boundaries: diff --git a/agents/flowblind-research-teammate-v2/release/flowblind-catalog-research-v2-verifier-release-v1.json b/agents/flowblind-research-teammate-v2/release/flowblind-catalog-research-v2-verifier-release-v1.json index a70850f2..73cd3aac 100644 --- a/agents/flowblind-research-teammate-v2/release/flowblind-catalog-research-v2-verifier-release-v1.json +++ b/agents/flowblind-research-teammate-v2/release/flowblind-catalog-research-v2-verifier-release-v1.json @@ -8,7 +8,7 @@ "lock": { "byteLength": 16667, "reference": "runtime/generated/data/flowblind-catalog-research-v2-package-lock-v1.json", - "sha256": "7b7a8955d8a1cb03b7cd0e983eaa788105e34bd50d730ed58d1c00b42fddfae8" + "sha256": "64f7fbfd042fac543e6d097838b2c4fa2cd28ce7a9fbbb4f05d691807bc29086" }, "packageId": "flowblind-research-teammate-v2", "packageVersion": "2.0.0", @@ -16,6 +16,6 @@ "verifier": { "byteLength": 36769, "reference": "runtime/flowblind-research-teammate-verification-v2.js", - "sha256": "09c35b5745ab453c5a1c0ffded90f88cf4fb803e8830d4e5495afed52fbe37bc" + "sha256": "8050fb71b8f50be40ca2e1dd0e92f0aab0f63efc39067512d2221cbead58bcac" } } diff --git a/agents/flowblind-research-teammate-v2/runtime/flowblind-research-teammate-verification-v2.js b/agents/flowblind-research-teammate-v2/runtime/flowblind-research-teammate-verification-v2.js index 71a41e43..681dfba2 100644 --- a/agents/flowblind-research-teammate-v2/runtime/flowblind-research-teammate-verification-v2.js +++ b/agents/flowblind-research-teammate-v2/runtime/flowblind-research-teammate-verification-v2.js @@ -61,7 +61,7 @@ export const expectedLockIdentity = Object.freeze({ byteLength: Number( '16667', ), - sha256: '7b7a8955d8a1cb03b7cd0e983eaa788105e34bd50d730ed58d1c00b42fddfae8', + sha256: '64f7fbfd042fac543e6d097838b2c4fa2cd28ce7a9fbbb4f05d691807bc29086', }) function throwIfAborted(signal) { diff --git a/agents/flowblind-research-teammate-v2/runtime/generated/data/flowblind-catalog-research-v2-package-lock-v1.json b/agents/flowblind-research-teammate-v2/runtime/generated/data/flowblind-catalog-research-v2-package-lock-v1.json index 4b28f51f..3c032f1a 100644 --- a/agents/flowblind-research-teammate-v2/runtime/generated/data/flowblind-catalog-research-v2-package-lock-v1.json +++ b/agents/flowblind-research-teammate-v2/runtime/generated/data/flowblind-catalog-research-v2-package-lock-v1.json @@ -163,10 +163,10 @@ "sha256": "be8edcd6c36df8dee5cb702c5a4afd55e5de39b99df7d398baec6f3adeb5b018" }, { - "byteLength": 12087, + "byteLength": 13360, "reference": "generated/data/package/README.md", "role": "package-readme", - "sha256": "b146205c7b69f964e1ec44a761bdff74422e15c8940df28fe3aa97c05eed6ec9" + "sha256": "543dc5a7d78cdc3b03305b5e744d069f3829472f37d5a87f8ff56ef886b9558c" }, { "byteLength": 3937, @@ -181,10 +181,10 @@ "sha256": "a449f9ffd53849a40901249907304b48ed296c84966eca52054b39b68c9f3b98" }, { - "byteLength": 1764, + "byteLength": 1877, "reference": "generated/data/package/flowblind-prepare.Dockerfile", "role": "prepare-docker-context", - "sha256": "c2070cdce465605045569c31af77055ffaf8ca21d0e0a505f658130bf571bec5" + "sha256": "46fc5f56e2b452bb8b27046b4ec9fe3f00a844afd4a01be46b82c0b775850324" }, { "byteLength": 6390, @@ -193,10 +193,10 @@ "sha256": "7008190973a4ae4744901820bc9581c07616565f4a705203b763588724b9294f" }, { - "byteLength": 1852, + "byteLength": 1965, "reference": "generated/data/package/flowblind-run-verify.Dockerfile", "role": "run-docker-context", - "sha256": "0d2884a0e5b10e6b68bdbb0700890d6ae50b6ce6c0df2bc3e7df3b4a426b8993" + "sha256": "4a1208289b5220a0cc666345621475225840046696eb02075195b3baa39dc5d0" }, { "byteLength": 2650, diff --git a/agents/flowblind-research-teammate-v2/runtime/generated/data/package/README.md b/agents/flowblind-research-teammate-v2/runtime/generated/data/package/README.md index c282f13a..092c4c29 100644 --- a/agents/flowblind-research-teammate-v2/runtime/generated/data/package/README.md +++ b/agents/flowblind-research-teammate-v2/runtime/generated/data/package/README.md @@ -90,6 +90,29 @@ decision. Preparation then also asks for approval; that is expected. The runtime requires no Git repository or repository metadata. +## Base image maintenance + +Both public tool images use the same pinned Node 26.11.1 and Python 3.12.14 +bases. The Node executable is copied into the Python final stage together +with its required `libatomic.so.1` library. `RUN node --version` makes a +missing loader dependency fail during the image build, before registration. + +A base-image update is a coordinated package change, not just a `FROM` edit: + +1. Update both tool Dockerfiles and their current canonical copies under + `runtime/generated/data/package/`. +2. Refresh the affected byte lengths and SHA-256 values in the current package + lock, the verifier's expected lock identity, and the verifier release record. +3. Keep both tool-local runtime trees byte-identical to the package runtime. + Do not rewrite retained historical manifests or enable private activation. +4. Run `npm test`, build both images for `linux/amd64`, and validate preparation + followed by execution using those exact images. Package tests check that + each outer Dockerfile matches its attested copy. + +The Python 3.12 wheel lock remains enforced with `--require-hashes`. A Python +minor-version migration needs separate wheel-lock and numerical compatibility +validation; the Node upgrade does not authorize or perform that migration. + ## Architecture The public lifecycle is deliberately split across two host-owned boundaries: diff --git a/agents/flowblind-research-teammate-v2/runtime/generated/data/package/flowblind-prepare.Dockerfile b/agents/flowblind-research-teammate-v2/runtime/generated/data/package/flowblind-prepare.Dockerfile index 9a3744bd..9fc2f8b6 100644 --- a/agents/flowblind-research-teammate-v2/runtime/generated/data/package/flowblind-prepare.Dockerfile +++ b/agents/flowblind-research-teammate-v2/runtime/generated/data/package/flowblind-prepare.Dockerfile @@ -1,5 +1,5 @@ # Both bases are pinned to their linux/amd64 manifests; build with --platform linux/amd64. -FROM node:22.22.0-bookworm-slim@sha256:7cc56ef285a8568121537d17b05e72128f01b89c54607b51acf084a50ef483f3 AS node-runtime +FROM node:26.11.1-bookworm-slim@sha256:86f07bc9c5dce4578cf37e5a418b7bfc7f817cda25cde66e2b66e95ed86c4567 AS node-runtime FROM python:3.12.14-slim@sha256:2fe5997d249a808b8eeea52c58a1dbffbba28754dc11699ef5c029f2d818ce79 @@ -32,6 +32,8 @@ RUN addgroup --system --gid 10001 flowblind \ && chown flowblind:flowblind /output COPY --from=node-runtime /usr/local/bin/node /usr/local/bin/node +COPY --from=node-runtime /usr/lib/x86_64-linux-gnu/libatomic.so.1* /usr/lib/x86_64-linux-gnu/ +RUN node --version COPY --chown=root:root runtime/ /app/runtime/ ARG PIP_INDEX_URL=https://pypi.org/simple diff --git a/agents/flowblind-research-teammate-v2/runtime/generated/data/package/flowblind-run-verify.Dockerfile b/agents/flowblind-research-teammate-v2/runtime/generated/data/package/flowblind-run-verify.Dockerfile index 241fb365..f2d6135a 100644 --- a/agents/flowblind-research-teammate-v2/runtime/generated/data/package/flowblind-run-verify.Dockerfile +++ b/agents/flowblind-research-teammate-v2/runtime/generated/data/package/flowblind-run-verify.Dockerfile @@ -1,5 +1,5 @@ # Both bases are pinned to their linux/amd64 manifests; build with --platform linux/amd64. -FROM node:22.22.0-bookworm-slim@sha256:7cc56ef285a8568121537d17b05e72128f01b89c54607b51acf084a50ef483f3 AS node-runtime +FROM node:26.11.1-bookworm-slim@sha256:86f07bc9c5dce4578cf37e5a418b7bfc7f817cda25cde66e2b66e95ed86c4567 AS node-runtime FROM python:3.12.14-slim@sha256:2fe5997d249a808b8eeea52c58a1dbffbba28754dc11699ef5c029f2d818ce79 @@ -33,6 +33,8 @@ RUN addgroup --system --gid 10001 flowblind \ && chown flowblind:flowblind /output COPY --from=node-runtime /usr/local/bin/node /usr/local/bin/node +COPY --from=node-runtime /usr/lib/x86_64-linux-gnu/libatomic.so.1* /usr/lib/x86_64-linux-gnu/ +RUN node --version COPY --chown=root:root runtime/ /app/runtime/ ARG PIP_INDEX_URL=https://pypi.org/simple diff --git a/agents/flowblind-research-teammate-v2/tests/portable-runtime.node-test.js b/agents/flowblind-research-teammate-v2/tests/portable-runtime.node-test.js index b0cde371..ae30a268 100644 --- a/agents/flowblind-research-teammate-v2/tests/portable-runtime.node-test.js +++ b/agents/flowblind-research-teammate-v2/tests/portable-runtime.node-test.js @@ -1682,6 +1682,19 @@ test('V2-PKG-001 V2-PKG-005 V2-PKG-006 V2-PKG-007 validate package mirrors and c ), 'utf8', ) + assert.equal( + dockerfile, + await readFile( + resolve( + packageRoot, + 'runtime/generated/data/package', + `${folder}.Dockerfile`, + ), + 'utf8', + ), + `${folder} Dockerfile must match its attested package copy`, + ) + assert.match(dockerfile, /^RUN node --version$/mu) assert.match(dockerfile, /USER 10001:10001/u) assert.match(dockerfile, /--require-hashes/u) assert.match( diff --git a/agents/flowblind-research-teammate-v2/tools/flowblind-prepare/Dockerfile b/agents/flowblind-research-teammate-v2/tools/flowblind-prepare/Dockerfile index 9a3744bd..9fc2f8b6 100644 --- a/agents/flowblind-research-teammate-v2/tools/flowblind-prepare/Dockerfile +++ b/agents/flowblind-research-teammate-v2/tools/flowblind-prepare/Dockerfile @@ -1,5 +1,5 @@ # Both bases are pinned to their linux/amd64 manifests; build with --platform linux/amd64. -FROM node:22.22.0-bookworm-slim@sha256:7cc56ef285a8568121537d17b05e72128f01b89c54607b51acf084a50ef483f3 AS node-runtime +FROM node:26.11.1-bookworm-slim@sha256:86f07bc9c5dce4578cf37e5a418b7bfc7f817cda25cde66e2b66e95ed86c4567 AS node-runtime FROM python:3.12.14-slim@sha256:2fe5997d249a808b8eeea52c58a1dbffbba28754dc11699ef5c029f2d818ce79 @@ -32,6 +32,8 @@ RUN addgroup --system --gid 10001 flowblind \ && chown flowblind:flowblind /output COPY --from=node-runtime /usr/local/bin/node /usr/local/bin/node +COPY --from=node-runtime /usr/lib/x86_64-linux-gnu/libatomic.so.1* /usr/lib/x86_64-linux-gnu/ +RUN node --version COPY --chown=root:root runtime/ /app/runtime/ ARG PIP_INDEX_URL=https://pypi.org/simple diff --git a/agents/flowblind-research-teammate-v2/tools/flowblind-prepare/runtime/flowblind-research-teammate-verification-v2.js b/agents/flowblind-research-teammate-v2/tools/flowblind-prepare/runtime/flowblind-research-teammate-verification-v2.js index 71a41e43..681dfba2 100644 --- a/agents/flowblind-research-teammate-v2/tools/flowblind-prepare/runtime/flowblind-research-teammate-verification-v2.js +++ b/agents/flowblind-research-teammate-v2/tools/flowblind-prepare/runtime/flowblind-research-teammate-verification-v2.js @@ -61,7 +61,7 @@ export const expectedLockIdentity = Object.freeze({ byteLength: Number( '16667', ), - sha256: '7b7a8955d8a1cb03b7cd0e983eaa788105e34bd50d730ed58d1c00b42fddfae8', + sha256: '64f7fbfd042fac543e6d097838b2c4fa2cd28ce7a9fbbb4f05d691807bc29086', }) function throwIfAborted(signal) { diff --git a/agents/flowblind-research-teammate-v2/tools/flowblind-prepare/runtime/generated/data/flowblind-catalog-research-v2-package-lock-v1.json b/agents/flowblind-research-teammate-v2/tools/flowblind-prepare/runtime/generated/data/flowblind-catalog-research-v2-package-lock-v1.json index 4b28f51f..3c032f1a 100644 --- a/agents/flowblind-research-teammate-v2/tools/flowblind-prepare/runtime/generated/data/flowblind-catalog-research-v2-package-lock-v1.json +++ b/agents/flowblind-research-teammate-v2/tools/flowblind-prepare/runtime/generated/data/flowblind-catalog-research-v2-package-lock-v1.json @@ -163,10 +163,10 @@ "sha256": "be8edcd6c36df8dee5cb702c5a4afd55e5de39b99df7d398baec6f3adeb5b018" }, { - "byteLength": 12087, + "byteLength": 13360, "reference": "generated/data/package/README.md", "role": "package-readme", - "sha256": "b146205c7b69f964e1ec44a761bdff74422e15c8940df28fe3aa97c05eed6ec9" + "sha256": "543dc5a7d78cdc3b03305b5e744d069f3829472f37d5a87f8ff56ef886b9558c" }, { "byteLength": 3937, @@ -181,10 +181,10 @@ "sha256": "a449f9ffd53849a40901249907304b48ed296c84966eca52054b39b68c9f3b98" }, { - "byteLength": 1764, + "byteLength": 1877, "reference": "generated/data/package/flowblind-prepare.Dockerfile", "role": "prepare-docker-context", - "sha256": "c2070cdce465605045569c31af77055ffaf8ca21d0e0a505f658130bf571bec5" + "sha256": "46fc5f56e2b452bb8b27046b4ec9fe3f00a844afd4a01be46b82c0b775850324" }, { "byteLength": 6390, @@ -193,10 +193,10 @@ "sha256": "7008190973a4ae4744901820bc9581c07616565f4a705203b763588724b9294f" }, { - "byteLength": 1852, + "byteLength": 1965, "reference": "generated/data/package/flowblind-run-verify.Dockerfile", "role": "run-docker-context", - "sha256": "0d2884a0e5b10e6b68bdbb0700890d6ae50b6ce6c0df2bc3e7df3b4a426b8993" + "sha256": "4a1208289b5220a0cc666345621475225840046696eb02075195b3baa39dc5d0" }, { "byteLength": 2650, diff --git a/agents/flowblind-research-teammate-v2/tools/flowblind-prepare/runtime/generated/data/package/README.md b/agents/flowblind-research-teammate-v2/tools/flowblind-prepare/runtime/generated/data/package/README.md index c282f13a..092c4c29 100644 --- a/agents/flowblind-research-teammate-v2/tools/flowblind-prepare/runtime/generated/data/package/README.md +++ b/agents/flowblind-research-teammate-v2/tools/flowblind-prepare/runtime/generated/data/package/README.md @@ -90,6 +90,29 @@ decision. Preparation then also asks for approval; that is expected. The runtime requires no Git repository or repository metadata. +## Base image maintenance + +Both public tool images use the same pinned Node 26.11.1 and Python 3.12.14 +bases. The Node executable is copied into the Python final stage together +with its required `libatomic.so.1` library. `RUN node --version` makes a +missing loader dependency fail during the image build, before registration. + +A base-image update is a coordinated package change, not just a `FROM` edit: + +1. Update both tool Dockerfiles and their current canonical copies under + `runtime/generated/data/package/`. +2. Refresh the affected byte lengths and SHA-256 values in the current package + lock, the verifier's expected lock identity, and the verifier release record. +3. Keep both tool-local runtime trees byte-identical to the package runtime. + Do not rewrite retained historical manifests or enable private activation. +4. Run `npm test`, build both images for `linux/amd64`, and validate preparation + followed by execution using those exact images. Package tests check that + each outer Dockerfile matches its attested copy. + +The Python 3.12 wheel lock remains enforced with `--require-hashes`. A Python +minor-version migration needs separate wheel-lock and numerical compatibility +validation; the Node upgrade does not authorize or perform that migration. + ## Architecture The public lifecycle is deliberately split across two host-owned boundaries: diff --git a/agents/flowblind-research-teammate-v2/tools/flowblind-prepare/runtime/generated/data/package/flowblind-prepare.Dockerfile b/agents/flowblind-research-teammate-v2/tools/flowblind-prepare/runtime/generated/data/package/flowblind-prepare.Dockerfile index 9a3744bd..9fc2f8b6 100644 --- a/agents/flowblind-research-teammate-v2/tools/flowblind-prepare/runtime/generated/data/package/flowblind-prepare.Dockerfile +++ b/agents/flowblind-research-teammate-v2/tools/flowblind-prepare/runtime/generated/data/package/flowblind-prepare.Dockerfile @@ -1,5 +1,5 @@ # Both bases are pinned to their linux/amd64 manifests; build with --platform linux/amd64. -FROM node:22.22.0-bookworm-slim@sha256:7cc56ef285a8568121537d17b05e72128f01b89c54607b51acf084a50ef483f3 AS node-runtime +FROM node:26.11.1-bookworm-slim@sha256:86f07bc9c5dce4578cf37e5a418b7bfc7f817cda25cde66e2b66e95ed86c4567 AS node-runtime FROM python:3.12.14-slim@sha256:2fe5997d249a808b8eeea52c58a1dbffbba28754dc11699ef5c029f2d818ce79 @@ -32,6 +32,8 @@ RUN addgroup --system --gid 10001 flowblind \ && chown flowblind:flowblind /output COPY --from=node-runtime /usr/local/bin/node /usr/local/bin/node +COPY --from=node-runtime /usr/lib/x86_64-linux-gnu/libatomic.so.1* /usr/lib/x86_64-linux-gnu/ +RUN node --version COPY --chown=root:root runtime/ /app/runtime/ ARG PIP_INDEX_URL=https://pypi.org/simple diff --git a/agents/flowblind-research-teammate-v2/tools/flowblind-prepare/runtime/generated/data/package/flowblind-run-verify.Dockerfile b/agents/flowblind-research-teammate-v2/tools/flowblind-prepare/runtime/generated/data/package/flowblind-run-verify.Dockerfile index 241fb365..f2d6135a 100644 --- a/agents/flowblind-research-teammate-v2/tools/flowblind-prepare/runtime/generated/data/package/flowblind-run-verify.Dockerfile +++ b/agents/flowblind-research-teammate-v2/tools/flowblind-prepare/runtime/generated/data/package/flowblind-run-verify.Dockerfile @@ -1,5 +1,5 @@ # Both bases are pinned to their linux/amd64 manifests; build with --platform linux/amd64. -FROM node:22.22.0-bookworm-slim@sha256:7cc56ef285a8568121537d17b05e72128f01b89c54607b51acf084a50ef483f3 AS node-runtime +FROM node:26.11.1-bookworm-slim@sha256:86f07bc9c5dce4578cf37e5a418b7bfc7f817cda25cde66e2b66e95ed86c4567 AS node-runtime FROM python:3.12.14-slim@sha256:2fe5997d249a808b8eeea52c58a1dbffbba28754dc11699ef5c029f2d818ce79 @@ -33,6 +33,8 @@ RUN addgroup --system --gid 10001 flowblind \ && chown flowblind:flowblind /output COPY --from=node-runtime /usr/local/bin/node /usr/local/bin/node +COPY --from=node-runtime /usr/lib/x86_64-linux-gnu/libatomic.so.1* /usr/lib/x86_64-linux-gnu/ +RUN node --version COPY --chown=root:root runtime/ /app/runtime/ ARG PIP_INDEX_URL=https://pypi.org/simple diff --git a/agents/flowblind-research-teammate-v2/tools/flowblind-run-verify/Dockerfile b/agents/flowblind-research-teammate-v2/tools/flowblind-run-verify/Dockerfile index 241fb365..f2d6135a 100644 --- a/agents/flowblind-research-teammate-v2/tools/flowblind-run-verify/Dockerfile +++ b/agents/flowblind-research-teammate-v2/tools/flowblind-run-verify/Dockerfile @@ -1,5 +1,5 @@ # Both bases are pinned to their linux/amd64 manifests; build with --platform linux/amd64. -FROM node:22.22.0-bookworm-slim@sha256:7cc56ef285a8568121537d17b05e72128f01b89c54607b51acf084a50ef483f3 AS node-runtime +FROM node:26.11.1-bookworm-slim@sha256:86f07bc9c5dce4578cf37e5a418b7bfc7f817cda25cde66e2b66e95ed86c4567 AS node-runtime FROM python:3.12.14-slim@sha256:2fe5997d249a808b8eeea52c58a1dbffbba28754dc11699ef5c029f2d818ce79 @@ -33,6 +33,8 @@ RUN addgroup --system --gid 10001 flowblind \ && chown flowblind:flowblind /output COPY --from=node-runtime /usr/local/bin/node /usr/local/bin/node +COPY --from=node-runtime /usr/lib/x86_64-linux-gnu/libatomic.so.1* /usr/lib/x86_64-linux-gnu/ +RUN node --version COPY --chown=root:root runtime/ /app/runtime/ ARG PIP_INDEX_URL=https://pypi.org/simple diff --git a/agents/flowblind-research-teammate-v2/tools/flowblind-run-verify/runtime/flowblind-research-teammate-verification-v2.js b/agents/flowblind-research-teammate-v2/tools/flowblind-run-verify/runtime/flowblind-research-teammate-verification-v2.js index 71a41e43..681dfba2 100644 --- a/agents/flowblind-research-teammate-v2/tools/flowblind-run-verify/runtime/flowblind-research-teammate-verification-v2.js +++ b/agents/flowblind-research-teammate-v2/tools/flowblind-run-verify/runtime/flowblind-research-teammate-verification-v2.js @@ -61,7 +61,7 @@ export const expectedLockIdentity = Object.freeze({ byteLength: Number( '16667', ), - sha256: '7b7a8955d8a1cb03b7cd0e983eaa788105e34bd50d730ed58d1c00b42fddfae8', + sha256: '64f7fbfd042fac543e6d097838b2c4fa2cd28ce7a9fbbb4f05d691807bc29086', }) function throwIfAborted(signal) { diff --git a/agents/flowblind-research-teammate-v2/tools/flowblind-run-verify/runtime/generated/data/flowblind-catalog-research-v2-package-lock-v1.json b/agents/flowblind-research-teammate-v2/tools/flowblind-run-verify/runtime/generated/data/flowblind-catalog-research-v2-package-lock-v1.json index 4b28f51f..3c032f1a 100644 --- a/agents/flowblind-research-teammate-v2/tools/flowblind-run-verify/runtime/generated/data/flowblind-catalog-research-v2-package-lock-v1.json +++ b/agents/flowblind-research-teammate-v2/tools/flowblind-run-verify/runtime/generated/data/flowblind-catalog-research-v2-package-lock-v1.json @@ -163,10 +163,10 @@ "sha256": "be8edcd6c36df8dee5cb702c5a4afd55e5de39b99df7d398baec6f3adeb5b018" }, { - "byteLength": 12087, + "byteLength": 13360, "reference": "generated/data/package/README.md", "role": "package-readme", - "sha256": "b146205c7b69f964e1ec44a761bdff74422e15c8940df28fe3aa97c05eed6ec9" + "sha256": "543dc5a7d78cdc3b03305b5e744d069f3829472f37d5a87f8ff56ef886b9558c" }, { "byteLength": 3937, @@ -181,10 +181,10 @@ "sha256": "a449f9ffd53849a40901249907304b48ed296c84966eca52054b39b68c9f3b98" }, { - "byteLength": 1764, + "byteLength": 1877, "reference": "generated/data/package/flowblind-prepare.Dockerfile", "role": "prepare-docker-context", - "sha256": "c2070cdce465605045569c31af77055ffaf8ca21d0e0a505f658130bf571bec5" + "sha256": "46fc5f56e2b452bb8b27046b4ec9fe3f00a844afd4a01be46b82c0b775850324" }, { "byteLength": 6390, @@ -193,10 +193,10 @@ "sha256": "7008190973a4ae4744901820bc9581c07616565f4a705203b763588724b9294f" }, { - "byteLength": 1852, + "byteLength": 1965, "reference": "generated/data/package/flowblind-run-verify.Dockerfile", "role": "run-docker-context", - "sha256": "0d2884a0e5b10e6b68bdbb0700890d6ae50b6ce6c0df2bc3e7df3b4a426b8993" + "sha256": "4a1208289b5220a0cc666345621475225840046696eb02075195b3baa39dc5d0" }, { "byteLength": 2650, diff --git a/agents/flowblind-research-teammate-v2/tools/flowblind-run-verify/runtime/generated/data/package/README.md b/agents/flowblind-research-teammate-v2/tools/flowblind-run-verify/runtime/generated/data/package/README.md index c282f13a..092c4c29 100644 --- a/agents/flowblind-research-teammate-v2/tools/flowblind-run-verify/runtime/generated/data/package/README.md +++ b/agents/flowblind-research-teammate-v2/tools/flowblind-run-verify/runtime/generated/data/package/README.md @@ -90,6 +90,29 @@ decision. Preparation then also asks for approval; that is expected. The runtime requires no Git repository or repository metadata. +## Base image maintenance + +Both public tool images use the same pinned Node 26.11.1 and Python 3.12.14 +bases. The Node executable is copied into the Python final stage together +with its required `libatomic.so.1` library. `RUN node --version` makes a +missing loader dependency fail during the image build, before registration. + +A base-image update is a coordinated package change, not just a `FROM` edit: + +1. Update both tool Dockerfiles and their current canonical copies under + `runtime/generated/data/package/`. +2. Refresh the affected byte lengths and SHA-256 values in the current package + lock, the verifier's expected lock identity, and the verifier release record. +3. Keep both tool-local runtime trees byte-identical to the package runtime. + Do not rewrite retained historical manifests or enable private activation. +4. Run `npm test`, build both images for `linux/amd64`, and validate preparation + followed by execution using those exact images. Package tests check that + each outer Dockerfile matches its attested copy. + +The Python 3.12 wheel lock remains enforced with `--require-hashes`. A Python +minor-version migration needs separate wheel-lock and numerical compatibility +validation; the Node upgrade does not authorize or perform that migration. + ## Architecture The public lifecycle is deliberately split across two host-owned boundaries: diff --git a/agents/flowblind-research-teammate-v2/tools/flowblind-run-verify/runtime/generated/data/package/flowblind-prepare.Dockerfile b/agents/flowblind-research-teammate-v2/tools/flowblind-run-verify/runtime/generated/data/package/flowblind-prepare.Dockerfile index 9a3744bd..9fc2f8b6 100644 --- a/agents/flowblind-research-teammate-v2/tools/flowblind-run-verify/runtime/generated/data/package/flowblind-prepare.Dockerfile +++ b/agents/flowblind-research-teammate-v2/tools/flowblind-run-verify/runtime/generated/data/package/flowblind-prepare.Dockerfile @@ -1,5 +1,5 @@ # Both bases are pinned to their linux/amd64 manifests; build with --platform linux/amd64. -FROM node:22.22.0-bookworm-slim@sha256:7cc56ef285a8568121537d17b05e72128f01b89c54607b51acf084a50ef483f3 AS node-runtime +FROM node:26.11.1-bookworm-slim@sha256:86f07bc9c5dce4578cf37e5a418b7bfc7f817cda25cde66e2b66e95ed86c4567 AS node-runtime FROM python:3.12.14-slim@sha256:2fe5997d249a808b8eeea52c58a1dbffbba28754dc11699ef5c029f2d818ce79 @@ -32,6 +32,8 @@ RUN addgroup --system --gid 10001 flowblind \ && chown flowblind:flowblind /output COPY --from=node-runtime /usr/local/bin/node /usr/local/bin/node +COPY --from=node-runtime /usr/lib/x86_64-linux-gnu/libatomic.so.1* /usr/lib/x86_64-linux-gnu/ +RUN node --version COPY --chown=root:root runtime/ /app/runtime/ ARG PIP_INDEX_URL=https://pypi.org/simple diff --git a/agents/flowblind-research-teammate-v2/tools/flowblind-run-verify/runtime/generated/data/package/flowblind-run-verify.Dockerfile b/agents/flowblind-research-teammate-v2/tools/flowblind-run-verify/runtime/generated/data/package/flowblind-run-verify.Dockerfile index 241fb365..f2d6135a 100644 --- a/agents/flowblind-research-teammate-v2/tools/flowblind-run-verify/runtime/generated/data/package/flowblind-run-verify.Dockerfile +++ b/agents/flowblind-research-teammate-v2/tools/flowblind-run-verify/runtime/generated/data/package/flowblind-run-verify.Dockerfile @@ -1,5 +1,5 @@ # Both bases are pinned to their linux/amd64 manifests; build with --platform linux/amd64. -FROM node:22.22.0-bookworm-slim@sha256:7cc56ef285a8568121537d17b05e72128f01b89c54607b51acf084a50ef483f3 AS node-runtime +FROM node:26.11.1-bookworm-slim@sha256:86f07bc9c5dce4578cf37e5a418b7bfc7f817cda25cde66e2b66e95ed86c4567 AS node-runtime FROM python:3.12.14-slim@sha256:2fe5997d249a808b8eeea52c58a1dbffbba28754dc11699ef5c029f2d818ce79 @@ -33,6 +33,8 @@ RUN addgroup --system --gid 10001 flowblind \ && chown flowblind:flowblind /output COPY --from=node-runtime /usr/local/bin/node /usr/local/bin/node +COPY --from=node-runtime /usr/lib/x86_64-linux-gnu/libatomic.so.1* /usr/lib/x86_64-linux-gnu/ +RUN node --version COPY --chown=root:root runtime/ /app/runtime/ ARG PIP_INDEX_URL=https://pypi.org/simple