fix(sms-bridge): target the v1 /session route prefix - #41
Merged
Conversation
PR #40 kept the documented v1 body and strict direct {info,parts} parsing but left the requests on the legacy V2 /api surface. Upstream v1.18.23 (ef2880f379129aa048be9e9353e30aa168d42c17) mounts the session HttpApi at root "/session": create = POST /session (empty body, direct Session.Info) and blocking prompt = POST /session/:sessionID/message (direct streamed SessionV1.WithParts). /api/session* is the distinct legacy V2 API (data-wrapped prompt admission, GET message listing, no /wait), so the strict direct-shape parser failed the live approved-source test with opencode-response-invalid. Switch only the route prefix in opencode-sms-bridge/server.py: POST /session with the documented empty body and POST /session/{id}/message with message-level agent + text parts. Response parsing, request bodies, and the bounded static error-code taxonomy are unchanged. Tests pin the exact /session prefix, methods, and bodies at the opener level and reject every /api route, /prompt, /wait, and prompt_async.
Restore the OSError failure fixture to a plain tuple element; the route-prefix change needs no other deviation from main's test file.
Image CI passedPre-commit validation passed. View the workflow run. |
14 tasks
xnoto
added a commit
to makeitworkcloud/kustomize-cluster
that referenced
this pull request
Sep 5, 2026
## Summary Select `ghcr.io/makeitworkcloud/opencode-sms-bridge:adb1e0e72729a7182b4a4929bd67e0275fba8173`, the immutable image published after [images PR #41](makeitworkcloud/images#41). It corrects the OpenCode v1.18.23 session route prefix from the incompatible legacy V2 `/api/session...` surface to the blocking HTTP-API `/session...` surface. **Verified producer evidence:** [images buildah run 33976054695](https://github.com/makeitworkcloud/images/actions/runs/33976054695) passed and published the selected immutable tag at digest `sha256:607a426dad63dd563cfcca9f9720a0bc5068a8d812b4d4dabd63a0291895bd30`. This PR changes only the bridge image tag in the existing `opencode-sms-bridge` Application. It changes no chart version, Secret, routing/allowlist, Service, TunnelBinding, or sync policy. Fixes # None — owner-authorized route-prefix repair rollout; no driving issue supplied. ## Type of change - [x] Bug fix - [ ] Feature / enhancement - [ ] Documentation - [ ] Infrastructure (OpenTofu root or module) - [x] GitOps desired state (manifests, kustomize, charts, SOPS/KSOPS secrets) - [ ] Container image - [ ] CI / reusable workflow - [ ] Refactor / cleanup - [ ] Breaking change ## Validation - [ ] Required pull-request checks pass — pending. Repository PR CI is the validation authority. - [x] Generated or centrally distributed files were regenerated by their owning automation, not hand-edited — none apply; this is a one-line immutable image-pin change. No local OpenTofu, SOPS, container build, cluster, or live-system operation was run or claimed. ## Impact and rollout **Producer:** `images` merged `adb1e0e…` and published the selected image. Publication is complete. **Consumer:** `workloads/apps/opencode-sms-bridge-app.yaml` is the canonical GitOps image-selection point. This PR proposes, but does not itself perform, selection or reconciliation. **Delivery stages:** source is merged, published, and verified by producer CI; GitOps selection is proposed and PR validation is pending. An authorized merge runs `test` on `main`; only a successful test triggers automatic root-sync submission. Root and child reconciliation, resource health, Pod image, and the approved-source SMS reply remain separate verification stages. **Rollback:** use a reviewed GitOps PR to restore the prior immutable tag `6b48ddeaa5897a3d07dc28aa929a941219ec8993`; do not retag images or patch live resources. ## Safety and secrets - [x] Contains no plaintext secrets, decrypted SOPS values, state files, kubeconfigs, tokens, or private endpoints - [x] No local OpenTofu init/plan/apply/destroy/import/state operations were run or claimed — plans come from pull-request checks - [x] Breaking or irreversible effects are described above with rollback notes AI-assisted change: an OpenCode agent materially produced this change; review the producer evidence, one-line diff, and automatic post-merge reconciliation behavior before merge.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The live approved-source SMS test against image
6b48ddereachedinbound_queued/job_claimedand then failedopencode-response-invalid. Root cause: PR #40 adopted the documentedv1 body and strict direct
{info,parts}parsing but left the requestson the legacy V2
/apisurface — an exact prefix/API mismatch.Authoritative upstream evidence at
anomalyco/opencodev1.18.23 commitef2880f379129aa048be9e9353e30aa168d42c17:packages/opencode/src/server/routes/instance/httpapi/groups/session.ts:const root = "/session";SessionPaths.create = "/session",SessionPaths.prompt = "/session/:sessionID/message".packages/opencode/src/server/routes/instance/httpapi/handlers/session.ts:createreturns the directSession.Info(empty body accepted);promptstreams the directSessionV1.WithParts{info,parts}JSON —neither is data-wrapped.
packages/opencode/test/server/httpapi-session.test.ts: proves thelegacy V2
/api/session/:id/promptadmission response is data-wrapped,GET
/api/session/:id/messageis the V2 message listing, and/api/session/:id/waitis unavailable —/apiand/sessionaredistinct APIs, so the strict direct-shape parser correctly rejected
the V2 response.
Changes, confined to
opencode-sms-bridge/server.pyandopencode-sms-bridge/test_server.py:POST /session(wasPOST /api/session) with thedocumented empty body; id still read from the direct
Session.Info.POST /session/{id}/message(was/api/session/{id}/message) with message-levelagent+ single textpart; response still parsed strictly as direct
{info,parts}./sessionprefix/method/body at the opener levelwith real request objects and reject every
/apiroute,/prompt,/wait, andprompt_async.Fixes #
None — owner-authorized evidence-based repair to the v1 route prefix;
no driving issue supplied.
Note: this repository has no pull-request template in
.github/, theroot, or
docs/; themakeitworkcloud/.githuborganization defaulttemplate is applied manually here.
Type of change
Validation
33975811487
(jobs checks
/ detect
/ build & push)
passed pre-commit (including Gitleaks), changed-image detection
(
opencode-sms-bridge), and the non-publishing bridge image build.The build's Containerfile step
RUN python3 -m unittest discover -s /app -p "test_*.py" -vran all 21 tests (Ran 21 tests in 0.100s — OK), including the exact/sessionroute/method/body flow test, thedocumented-fields-only session-create test, the single blocking
message-request test, the
/api-route rejection assertions, and thestrict
{info,parts}extraction and invalid-shape rejection tests.Push to registrywas correctly skipped in PR mode.owning automation, not hand-edited — none changed; only
opencode-sms-bridge/server.pyandopencode-sms-bridge/test_server.pywere edited.
No local tests, container builds, OpenTofu, SOPS, state, or live-system
operations were run or claimed. CI is the validation authority.
Impact and rollout
Producer changed:
makeitworkcloud/images/opencode-sms-bridgeis thecanonical bridge-image source. An approved merge automatically publishes
a new immutable GHCR image tag; this PR neither publishes nor deploys
anything itself.
Consumer unchanged:
kustomize-clustercontinues to select itscurrently pinned image; this PR makes no GitOps or image-selection
change. After an approved merge and publication, a separate reviewed
GitOps PR and explicit confirmation are required before image selection,
Argo reconciliation, health verification, and a new approved-source SMS
test.
Behavior boundary: a text job now issues
POST /sessionwith anempty body and
POST /session/{id}/messagewith the routing agent and atext part, instead of the same documented bodies on the legacy V2
/api/session...prefix. Persisted detail codes are unchanged inliteral value (
opencode-request-failed:<session-create|prompt>:<category>,opencode-response-invalid, etc.). Direct V1 shapes parse as before;legacy
data-wrapped envelopes remain rejected.Rollback: if a later selected image regresses, use the canonical
GitOps workflow to select a reviewed immutable image tag. Do not
overwrite image tags or alter live state manually.
Safety and secrets
kubeconfigs, tokens, or private endpoints.
were run or claimed — plans come from pull-request checks.
notes.
AI-assisted change: an OpenCode agent materially produced this change;
reviewers should verify the cited v1.18.23 upstream evidence (the
/sessionroot withcreate = /sessionandprompt = /session/:sessionID/message, directSession.Info/SessionV1.WithPartsresponses, and the distinct legacy V2
/apisurface), the strictresponse parsing and its invalid-shape rejection, the unchanged bounded
taxonomy, and CI results before merge.