Package Relaycast self-host image for Ratify federation - #317
Conversation
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
|
Warning Review limit reached
Next review available in: 18 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (8)
📝 WalkthroughWalkthroughAdds a pinned, multi-architecture Relaycast container deployment. The change includes HTTPS base URL validation, Docker Compose configuration, persistent storage, operational procedures, entrypoint tests, and CI checks for container tests and ARM64/AMD64 builds. ChangesContainer deployment
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Suggested labels: Sequence Diagram(s)sequenceDiagram
participant DockerCompose
participant Entrypoint
participant RelaycastEngine
participant HealthCheck
DockerCompose->>Entrypoint: Start with RELAYCAST_BASE_URL
Entrypoint->>Entrypoint: Validate HTTPS origin
Entrypoint->>RelaycastEngine: Launch with normalized arguments
HealthCheck->>RelaycastEngine: Request health endpoint
RelaycastEngine-->>HealthCheck: Return health status
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
| Packages without a separate changelog are covered by the cross-package notes below. | ||
|
|
||
| ## [Unreleased] | ||
| ## [Unreleased - Patch] |
There was a problem hiding this comment.
🟡 Release notes label a new feature as a patch-level release
The pending release heading is set to patch level (## [Unreleased - Patch] at CHANGELOG.md:19) even though the entry below it is an ### Added new-feature note, so the next release would be cut at the wrong version level.
Impact: Consumers see a new capability shipped under a patch version bump, contradicting the project's stated versioning promise.
Changelog release-level rule in AGENTS.md
AGENTS.md requires: "The first pending user-visible change must set the heading to [Unreleased - Patch], [Unreleased - Minor], or [Unreleased - Major] according to its SemVer impact." The only pending entry is an addition (a new self-host container/Compose deployment path), which is a minor-level change under SemVer, not a patch. The publish workflow (scripts/cut-changelog.mjs) uses this heading to derive the release level.
| ## [Unreleased - Patch] | |
| ## [Unreleased - Minor] |
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a39a9d0d83
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| Packages without a separate changelog are covered by the cross-package notes below. | ||
|
|
||
| ## [Unreleased] | ||
| ## [Unreleased - Patch] |
There was a problem hiding this comment.
Mark the new container feature as a minor release
This commit adds a new user-visible deployment capability—a supported multi-architecture container, Compose configuration, and operations runbook—rather than merely fixing existing behavior. Classifying it as Patch understates its SemVer impact and can allow the next release to be cut with the wrong bump; change this pending heading to [Unreleased - Minor].
AGENTS.md reference: AGENTS.md:L38-L41
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 8
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/ci.yml:
- Line 38: Update the actions/checkout@v4 step in the CI workflow to set
persist-credentials to false, ensuring the checkout does not retain GITHUB_TOKEN
credentials for subsequent steps.
- Around line 27-30: Update the container job configuration in the CI workflow
to set its default permissions to contents: read, ensuring run-only steps do not
inherit write access while preserving the existing container settings.
In `@CHANGELOG.md`:
- Around line 19-23: Update the changelog heading from “[Unreleased - Patch]” to
“[Unreleased - Minor]” to classify the new user-facing self-host deployment
capability as a feature addition, leaving the added entry unchanged.
In `@docker-compose.yml`:
- Around line 35-37: Update the relaycast-data volume declaration to avoid the
explicit unscoped name, allowing Docker Compose to apply project scoping; only
use an external pre-created volume if the deployment requires it, and then
document its creation and usage in RUNBOOK.md.
- Around line 23-28: Update the healthcheck command in the healthcheck
configuration to parse the `/health` response body and require `body.ok ===
true`, while retaining failure handling for non-OK HTTP responses and request
errors. Keep the implementation aligned with the documented contract in
RUNBOOK.md.
In `@docker/entrypoint.mjs`:
- Around line 119-152: Update validatedEngineArgs to reject any second
--base-url occurrence before appending or validating it, covering both
separate-value and --base-url= forms; preserve the existing missing-value
refusal and single-value validation behavior, and add a regression test for
mixed valid and invalid duplicate options.
In `@docs/self-hosting.md`:
- Around line 201-204: Use non-destructive .env setup in both documented paths:
in docs/self-hosting.md lines 201-204, guard creation before writing
RELAYCAST_BASE_URL; in RUNBOOK.md lines 40-44, apply the same guard before
writing RELAYCAST_BASE_URL and RELAYCAST_PORT, preserving existing Compose
settings instead of overwriting them.
- Around line 219-223: Update the upgrade guidance to keep the repository image
tag synchronized with docker-compose.yml at the new version, and instruct
updating the installed engine-version check to that same version as documented
in RUNBOOK.md. Preserve the existing migration and federation-peer guidance.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 77970e07-95dc-4ab8-b712-fd1b5ef125c4
⛔ Files ignored due to path filters (1)
docker/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (12)
.dockerignore.github/workflows/ci.yml.github/workflows/deploy.ymlCHANGELOG.mdDockerfileRUNBOOK.mddocker-compose.ymldocker/entrypoint.mjsdocker/package.jsondocs/self-hosting.mdpackage.jsontest/container-entrypoint.test.mjs
There was a problem hiding this comment.
2 issues found across 13 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="docs/self-hosting.md">
<violation number="1" location="docs/self-hosting.md:220">
P3: The image's engine version is pinned in more places than the doc suggests, so following the upgrade instruction alone leaves tags/labels stale. Besides `docker/package.json` (dep + `version`), the version is also hardcoded in `Dockerfile`'s `org.opencontainers.image.version`/`io.relaycast.engine.version` LABELs and in `docker-compose.yml`'s `image: relaycast-self-host:7.0.0`, so bumping only the engine dep + lockfile produces a rebuilt image still tagged `relaycast-self-host:7.0.0` and labeled 7.0.0. Consider listing all the version-pin locations that must be updated together so the rebuild is self-consistent.</violation>
</file>
<file name="Dockerfile">
<violation number="1" location="Dockerfile:29">
P3: The engine version 7.0.0 is repeated in four places (Dockerfile LABELs, the compose `image:` tag, and docker/package.json version) so it must be bumped in lockstep manually. On a future engine upgrade, it's easy to update `@relaycast/engine` and the lockfile but forget the LABELs and image tag, leaving image metadata and the compose tag asserting a version that no longer matches the shipped engine. Since the runbook and health meta deliberately surface this version string, centralizing it (e.g., `ARG RELAYCAST_ENGINE_VERSION`/`ENV` read from one source, or deriving the tag) would remove the drift risk.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| then restart. New migrations apply automatically on boot; already-applied ones | ||
| are skipped. | ||
| - **Upgrade**: for a global install, run | ||
| `npm install -g @relaycast/engine@<tested-version>`. For the repository image, |
There was a problem hiding this comment.
P3: The image's engine version is pinned in more places than the doc suggests, so following the upgrade instruction alone leaves tags/labels stale. Besides docker/package.json (dep + version), the version is also hardcoded in Dockerfile's org.opencontainers.image.version/io.relaycast.engine.version LABELs and in docker-compose.yml's image: relaycast-self-host:7.0.0, so bumping only the engine dep + lockfile produces a rebuilt image still tagged relaycast-self-host:7.0.0 and labeled 7.0.0. Consider listing all the version-pin locations that must be updated together so the rebuild is self-consistent.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/self-hosting.md, line 220:
<comment>The image's engine version is pinned in more places than the doc suggests, so following the upgrade instruction alone leaves tags/labels stale. Besides `docker/package.json` (dep + `version`), the version is also hardcoded in `Dockerfile`'s `org.opencontainers.image.version`/`io.relaycast.engine.version` LABELs and in `docker-compose.yml`'s `image: relaycast-self-host:7.0.0`, so bumping only the engine dep + lockfile produces a rebuilt image still tagged `relaycast-self-host:7.0.0` and labeled 7.0.0. Consider listing all the version-pin locations that must be updated together so the rebuild is self-consistent.</comment>
<file context>
@@ -195,34 +195,32 @@ WorkingDirectory=/var/lib/relaycast
- then restart. New migrations apply automatically on boot; already-applied ones
- are skipped.
+- **Upgrade**: for a global install, run
+ `npm install -g @relaycast/engine@<tested-version>`. For the repository image,
+ update the exact engine version and lockfile only after confirming federation
+ peers use the same version, then rebuild. New migrations apply automatically
</file context>
| org.opencontainers.image.description="Single-process Relaycast engine with SQLite persistence" \ | ||
| org.opencontainers.image.source="https://github.com/AgentWorkforce/relaycast" \ | ||
| org.opencontainers.image.version="7.0.0" \ | ||
| io.relaycast.engine.version="7.0.0" |
There was a problem hiding this comment.
P3: The engine version 7.0.0 is repeated in four places (Dockerfile LABELs, the compose image: tag, and docker/package.json version) so it must be bumped in lockstep manually. On a future engine upgrade, it's easy to update @relaycast/engine and the lockfile but forget the LABELs and image tag, leaving image metadata and the compose tag asserting a version that no longer matches the shipped engine. Since the runbook and health meta deliberately surface this version string, centralizing it (e.g., ARG RELAYCAST_ENGINE_VERSION/ENV read from one source, or deriving the tag) would remove the drift risk.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At Dockerfile, line 29:
<comment>The engine version 7.0.0 is repeated in four places (Dockerfile LABELs, the compose `image:` tag, and docker/package.json version) so it must be bumped in lockstep manually. On a future engine upgrade, it's easy to update `@relaycast/engine` and the lockfile but forget the LABELs and image tag, leaving image metadata and the compose tag asserting a version that no longer matches the shipped engine. Since the runbook and health meta deliberately surface this version string, centralizing it (e.g., `ARG RELAYCAST_ENGINE_VERSION`/`ENV` read from one source, or deriving the tag) would remove the drift risk.</comment>
<file context>
@@ -0,0 +1,46 @@
+ org.opencontainers.image.description="Single-process Relaycast engine with SQLite persistence" \
+ org.opencontainers.image.source="https://github.com/AgentWorkforce/relaycast" \
+ org.opencontainers.image.version="7.0.0" \
+ io.relaycast.engine.version="7.0.0"
+
+ENV NODE_ENV=production \
</file context>
There was a problem hiding this comment.
All reported issues were addressed across 8 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
There was a problem hiding this comment.
All reported issues were addressed across 3 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/ci.yml:
- Around line 64-70: Update the assert_refused helper to wrap the docker run
command with timeout, using a short test-appropriate duration so regressions
that start the server fail promptly while preserving the existing refusal.log
capture and refusal-message validation.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 2679db02-f95a-4ea7-886a-35c920c1639d
📒 Files selected for processing (8)
.github/workflows/ci.ymlCHANGELOG.mdDockerfileRUNBOOK.mddocker-compose.ymldocker/entrypoint.mjsdocs/self-hosting.mdtest/container-entrypoint.test.mjs
🚧 Files skipped from review as they are similar to previous changes (3)
- docker-compose.yml
- CHANGELOG.md
- docs/self-hosting.md
There was a problem hiding this comment.
All reported issues were addressed across 7 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
26553f7 to
06bc496
Compare
Summary
node:22.23.2-bookworm-slimbase@relaycast/engine@7.0.0, force the nativebetter-sqlite3source build, and fail the build if package and image version metadata drift--base-urlis provided exactly once as an HTTPS, multi-label public DNS origin with valid bounded labels;.local,.localhost, all IP literals, loopback authorities, and malformed option-value layouts fail before opening a socketlinux/amd64andlinux/arm64PR CI, with bounded refusal and accepted-origin controlsFederation version parity
This image pins engine 7.0.0.
Hosted
cast.agentrelay.comis also confirmed on engine 7.0.0: the privateAgentWorkforce/relaycast-cloudlockfile resolves 7.0.0, and its 7.0.0 rebundle commit599e4163d7c74f3fb284efd4b048998bb20945a1completed the productionSST deploysuccessfully in run 31211768363.The hosted
/healthresponse saysversion: 1.0.0; that is the gateway application version, not the engine dependency. The runbook prevents operators from using that field as skew evidence.Release gate: standard A2A discovery
Published engine 7.0.0 has a production-confirmed discovery defect. On a three-label host, bare
GET /.well-known/agent-card.jsontreats the first host label as the workspace name, and host inference also shadows the documented path-param form. The explicit?workspace=ratify-protocolform works, but it is not the standard bare discovery URL a counterparty will try.The source fix now exists in PR #318 at commit
d5dcc954597c274e6e9cc87391f30e51a9f4f46a, but its package still reports 7.0.0 and it is not published or deployed. A stock published 7.0.0 artifact cannot contain it.The runbook keeps Ratify's meaningful workspace name and documents the query form only as an interim operator check. Do not hand this image to Ratify as federation-ready until either:
A self-host-only overlay would create the version skew this package is designed to prevent.
Validation
npm run test:container: 14/14 pass; every test contains an inverse control, including.local, IPv4, IPv6, malformed DNS labels, and symlink-invocation regressions{ "ok": true }, and advertiseshttps://relay.ratifyprotocol.com/a2a/rpceven when its tunnel-side request has a deliberately wrong HTTP authoritylinux/amd64: pass in 1m51slinux/arm64: pass in 10m12s.local,.localhost, loopback, IPv4, IPv6, and malformed arguments, checked package/label version equality, validated semantic health, created the Ratify workspace, and checked the HTTPS agent-card RPC URLdocker compose up --build --wait: pass under the read-only/capability-dropped configuration; project-scoped volume, database, file directory, and health state verifiednpx turbo lint: passnpx turbo testunder Node 22: 18/18 Turbo tasks passnpx turbo buildunder Node 22: 9/9 tasks passOperational notes
POST /v1/workspacesunauthenticated. The runbook bootstraps locally before exposure and blocks that exact public path atcloudflared; omitting the block would permit storage abuse.@hono/node-serverWindows encoded-backslash advisory (moderate, no compatible upstream fix). This image supports Linux only, so that Windows-only path traversal is not applicable to the delivered runtime.No image is published and nothing is deployed or merged by this PR.