Skip to content

Install the pinned reachability engine in the Docker image - #345

Draft
lelia wants to merge 1 commit into
mainfrom
lelia/ce-431-coana-pin
Draft

Install the pinned reachability engine in the Docker image#345
lelia wants to merge 1 commit into
mainfrom
lelia/ce-431-coana-pin

Conversation

@lelia

@lelia lelia commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Problem

Dockerfile installed @coana-tech/cli unpinned, while the launcher asks npx for the version in DEFAULT_COANA_CLI_VERSION. npx reuses the image's global install only when the versions match; on a mismatch it downloads the engine again on every scan.

Measured in the published image:

Requested version Launcher npm cache delta
matches the global install 3s 0 MB
mismatched 9s +119 MB

The two agreed only because release rebuilds happened to follow the pin bumps. Nothing enforced it, and the failure mode is silent — no error, no test failure, just slower scans and extra egress.

Change

  • The Dockerfile reads the pinned version out of reachability.py and installs exactly that, failing the build if the value cannot be read. The pin stays bumped in one place, so the image and the runtime cannot drift.
  • The coana install moves out of the toolchain RUN. A pin bump now rebuilds a 353 MB layer instead of the 2.3 GB combined layer.
  • Marking a release stable builds that version from its own tag. The image installs socketsecurity==inputs.version from PyPI, so building from the default branch paired an old wheel with a newer build recipe and pin.
  • tests/unit/test_dockerfile_coana_pin.py runs the Dockerfile's own extraction expression against the real source and rejects an unpinned install. Dockerfile was added to the unit-test path filter so the guard runs on Dockerfile-only changes.

Verification

  • Full image build: baked engine, runtime pin and source all report 15.10.36; socketcli --help and coana-cli both work.
  • Building against a source file with the constant renamed aborts with Could not read DEFAULT_COANA_CLI_VERSION from reachability.py rather than silently installing unpinned.
  • After the change npx resolves without downloading — metadata only, no cache growth.
  • Both guards fail on their respective mutations and pass when reverted.
  • 425 unit tests pass, 2 pre-existing skips. The extraction expression was checked under both BSD and busybox sed.

e2e-reachability needs to run here — this changes how the engine is installed, so it is the meaningful gate.

Not included

socket npm is still installed unpinned and the npm cache is still shipped in the image. Both are tracked separately.


Refs: CE-431


Note

Medium Risk
Changes how the published Docker image installs the reachability engine and how stable releases are built; wrong pinning would affect every containerized scan but is guarded by build failure and new unit tests.

Overview
Fixes a silent mismatch where the Docker image installed unpinned @coana-tech/cli while scans invoke npx with DEFAULT_COANA_CLI_VERSION from reachability.py — when versions diverged, npx re-downloaded the engine on every scan (extra time and egress).

The Dockerfile now copies reachability.py, extracts the pin with the same sed logic used at build time, and npm installs that exact version (build fails if the constant cannot be read). The Coana install is split into its own layer so pin bumps rebuild a smaller layer instead of the full toolchain step. Release 2.7.2 bumps package version and changelog accordingly.

Mark release stable (docker-stable.yml) now checks out v${{ inputs.version }} so stable images are built from that tag’s Dockerfile/pin, not main paired with an older PyPI wheel.

CI adds tests/unit/test_dockerfile_coana_pin.py (sed extraction + no unpinned Coana install) and runs unit tests when Dockerfile changes.

Reviewed by Cursor Bugbot for commit 21a802d. Configure here.

The image installed @coana-tech/cli unpinned while the launcher asks npx for
DEFAULT_COANA_CLI_VERSION. npx reuses the global install only when the versions
match, so once the two diverged every scan re-downloaded the engine (~119 MB)
and the launcher took roughly three times as long, silently. The Dockerfile now
reads the pinned version out of reachability.py, so the image and the runtime
cannot drift and the pin stays bumped in exactly one place.

Splitting the coana install out of the toolchain RUN keeps a pin bump to a
353 MB layer rather than rebuilding the 2.3 GB combined layer.

Marking a release stable now builds that version from its own tag, so an older
wheel is no longer paired with the default branch's build recipe and pin.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@lelia
lelia requested a review from a team as a code owner September 7, 2026 18:11
@lelia
lelia deployed to socket-firewall September 7, 2026 18:11 — with GitHub Actions Active
@lelia
lelia marked this pull request as draft September 8, 2026 21:22
@lelia

lelia commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

bugbot run

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issue.

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 21a802d. Configure here.

# socketsecurity==inputs.version from PyPI, and the Dockerfile reads the pinned
# @coana-tech/cli version out of the checked-out source, so building from the
# default branch would pair an old wheel with a newer build recipe and pin.
ref: v${{ inputs.version }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stable build ignores tag checkout

Medium Severity

The new tag checkout does not feed the image build. docker/build-push-action still uses the workflow Git context from the dispatch branch, so the Dockerfile and reachability.py come from that branch while CLI_VERSION installs the requested wheel. Rebuilding an older stable after main has moved recreates the pin mismatch.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 21a802d. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant