Skip to content

fix(companions): proto 0.0.18 for the streaming facade; refuse an unbumped companion change - #838

Merged
antoinetoussaint-byte merged 3 commits into
mainfrom
fix/837-proto-companion-version
Oct 26, 2026
Merged

antoinetoussaint-byte merged 3 commits into
mainfrom
fix/837-proto-companion-version

Conversation

@antoinetoussaint-byte

Copy link
Copy Markdown
Contributor

Closes #837.

Why

08716e9 changed companions/proto/facades/python/protoc_gen_codefly_facade_python.py (streaming RPCs get their own gateway seams) and kept proto at 0.0.17. 0.0.17 had already been published with the old plugin (sha256:aa8d63e1) and was then republished with the new one (sha256:46e8b398). A machine that cached the first image keeps it, because the CLI reuses a cached tag. That is how obin-ai/module-model-gateway#210's Python model client came out with its four streaming RPCs as unary. codefly-dev/cli#1161's generator test fails against the first image and passes against the second.

Change

  1. companions/proto/info.codefly.yaml → 0.0.18. The plugin change now ships under a tag no machine has cached. README notes which version carries the streaming facade.
  2. internal/companionbump: go run ./internal/companionbump <base-ref>. A new version job in companions-build.yml runs it on every pull request; the path filter also covers internal/companionbump/**.
    • Each companion's image inputs come from BuildSpec.Inputs: its Dockerfile plus every build-context COPY source, read from the Dockerfile itself. The staged CLI binary is excluded because it is built from codefly-dev/cli.
    • If a file under any input changed since the merge base, the companion's version must be above its version at the base's tip. Using the tip also refuses a version that another merged change already took (two images, one tag).
    • A new companion and a change outside the inputs (README, testdata) need no bump.
  3. companions.CopySources / CopyKind: the COPY parser buildspec_test.go already had, moved into the package so the check and the tests read Dockerfiles one way. The tests now call it. No second parser.

Evidence

  • Against history: in a worktree at 08716e9 with this check copied in, go run ./internal/companionbump 08716e9^ refuses it, exit 1:
    companion <proto> changes its image (companions/proto/facades/python/protoc_gen_codefly_facade_python.py) but companions/proto/info.codefly.yaml says 0.0.17, and the base says 0.0.17: bump it above 0.0.17
  • On this branch vs origin/main, it passes.
  • go test ./internal/companionbump ./internal/buildspecs ./companions/ ./companions/proto/ pass. Unit cases: unbumped refused, bumped passes, version already taken on the base refused, non-input and prefix-sibling paths ignored, new companion passes. One test also runs over the real specs.
  • golangci-lint on the touched packages adds no new findings; the goconst hits in buildspec.go/companions.go were already on main.

After merge

Publishing is a separate step: run the CLI's Companions workflow with core_ref = this merge commit to push proto:0.0.18. Then the CLI moves its core pin, and the CLI's verify gate needs 0.0.18 in the registry before that. I'll open the CLI pin PR once this merges.

Classification

Fix, at the owner: core owns companion versions and their build inputs. Reused: BuildSpecs, the existing COPY parser, the existing companions-build workflow. Not done: the Nix flake (companions/proto/flake.nix) is a local-only build definition and is not counted as an input. The published image comes from the Dockerfile.

🤖 Generated with Claude Code

…umped companion change

08716e9 changed the proto companion's Python facade plugin and kept
0.0.17. 0.0.17 had been published with the old plugin, then was
republished with the new one, so a machine that cached the first image
still renders every streaming RPC as `unary` (obin-ai/module-model-
gateway#210's model client). Proto moves to 0.0.18, a tag no machine has
cached.

internal/companionbump, run by companions-build on every pull request,
refuses a change to a companion's image inputs (its Dockerfile and
every build-context COPY source: BuildSpec.Inputs) unless the
companion's version is above the base's. Comparing with the base's tip
also refuses a version another merged change already took. Run against
08716e9 it refuses exactly that change.

The COPY parser the buildspec tests used moves into the package
(CopySources) so the check and the tests read Dockerfiles one way.

Closes #837

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
antoinetoussaint-byte and others added 2 commits October 25, 2026 21:04
…y copy shape count

Review r65 on #838:
- The check moves to its own workflow with no path filter, so it reports
  on every pull request and can be a required check of main's ruleset (a
  path-filtered required check stays pending on a PR it skips).
- git diff runs with --no-renames: moving a file out of an input lists
  it at its old path too, so it no longer escapes. A test in a scratch
  repository fails without the flag.
- The Dockerfile reader takes logical instructions (continued lines
  joined, comments inside them dropped) and reads ADD as well as COPY, in
  any case. An ADD of a URL or git remote and a heredoc are not context
  inputs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…fe to require

companion-version.yml runs on every pull request with a fixed job name,
so ciguard derives it as safe to require; the pinned set and the
branch-protection runbook's apply payload name it too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

proto companion: 08716e9 changed the Python facade plugin without bumping 0.0.17, so cached 0.0.17 images still render streaming RPCs as unary

1 participant