chore(sync): develop → main — the Tracker↔Core seam is now tested by CI - #145
Merged
Conversation
…d by CI (#144) * feat(ci): deploy the Core from GHCR so the Tracker↔Core seam is tested by CI `core-integration` asserts the SIX interfaces of the pair and had never run in this pipeline: it needs the Core, another product, which nothing here deployed. So the seam was verified by hand or not at all. The first time it ran against a real stack it found three defects invisible to every other suite, two of them product defects — one in each repository. The Core already publishes all three service images to GHCR on every merge to its main, tagged with the commit SHA as well as `latest`. That SHA tag is what makes this safe to wire. PINNED, not `latest`, and the file says why: following the Core's tip would turn this repository's pull requests red for a defect merged minutes earlier by someone who has never seen this pipeline. A pinned SHA moves that failure into a diff with a reviewer. The accepted cost is that `core-image.sha` goes stale on purpose and somebody has to raise it — the same discipline the charts already use for their own tags. The Core is deployed by a MINIMAL manifest of this repository's own, not by vendoring its charts: those live in the other repo, would drift here, and would drag in OPA sidecars, HPAs and IngressRoutes this test neither needs nor can maintain. It is a fixture, and it says so. It pins uid 1001 because pinning 1000 is what made the deployed MCP unable to read its own policy.wasm (evolith_arch32#425). `core-integration` enters the robot list only when the Core is actually present, and when it is absent the run SAYS so instead of quietly shrinking — a suite that silently drops its only cross-product robot reads exactly like one that passed it. The gateway also joins the local install: steps 1-4 of that robot go through it, which is part of why the robot was excluded. Verified on a live kind cluster, not argued: the Core rolls out from the pinned refs, the gateway reaches it by in-cluster DNS, and the full suite runs 11 robots — 242 passed, 0 failed, `core-integration` 13/13. Both branches of the inclusion predicate were exercised. NOT verified here, and stated rather than implied: the `docker pull` itself. The packages are PRIVATE, which the first local attempt proved by answering `unauthorized` — and that failure is what exposed the two things missing from this wiring, now fixed: `packages: read` on the workflow and a GHCR login step before the pull. The local run used the same image refs loaded by hand, so everything downstream of the pull is proven and the pull is exercised the first time this lands. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(ci): one local key, not three, for the same deployment CI ran the seam for the first time and failed on exactly one check: `POST /assistant/converse` → 502. The cause is a three-way mismatch that existed before this change and could not be seen until now. The same local deployment carried three different credentials: this script wrote `local-only-not-a-real-key-core` and `local-only-not-a-real-key-runtime`, while the gateway chart defaults to `local-dev-key`. With the Core outside the cluster nobody ever authenticated against it, so nothing disagreed. The moment the Core came in, every step that goes THROUGH the gateway passed — both ends were `local-dev-key` — and the one step that goes straight from tracker-api to the agent-runtime got 401. What made it expensive to read: that 401 reaches the caller as 502 (LV-26), so a credential problem arrives dressed as an availability problem. It cost time on a laptop two days ago and it cost this run. One key everywhere now. It is a local test credential and its name says so; the value does not matter as long as all three agree. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(ci): point tracker-api at the Core this pipeline deploys Step 6 of `core-integration` kept returning 502 and the previous commit blamed the wrong thing. Aligning the local keys was correct on its own — three credentials for one deployment is a defect — but it was not this. `values-local.yaml` points the tracker-api at `evolith-runtime-evolith-agent-runtime.evolith-local`: the service names the CORE's Helm chart generates, in the Core's own namespace. This pipeline has neither. It deploys a minimal fixture as `core-agent-runtime` in `evolith-core-local`, so the tracker-api was calling a host that does not resolve — and an unresolvable host surfaces as 502, which reads as "the runtime is down" rather than "the URL points nowhere". I set these by hand on a laptop two days ago and never wired them into `install()`. CI ran the path I had only ever run manually, and that is precisely what it is for. Set unconditionally, including when the Core is absent: it is configuration, not a boot dependency, and a nonexistent host fails exactly as the previous one did. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(ci): retire the Core fixture before the production redeploy The robots pass — 242, 0 failed, `core-integration` included — and the step AFTER them broke: the production redeploy timed out with `context deadline exceeded`. Not resource pressure, which is what I assumed first. The log names it: the tracker-api's readiness probe runs a `core-capabilities` health check that calls the Core, and under the PRODUCTION profile `networkPolicy` is enabled, blocking egress to the Core's namespace. The call hangs until it cancels, the pod never reaches Ready, and helm --wait gives up after five minutes. Without a Core the same URL simply does not resolve and fails fast, which is the condition that step was written under and why it has been green on develop for months. So the fixture is retired as soon as the test that needs it is done. It was never part of the Tracker's deployment; it is scaffolding for one step, and leaving it standing changed the conditions of every step after. `if: always()` so a failing robot run still cleans up and the production steps are judged on their own terms. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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.
Brings #144 to
main.core-integrationasserts the six interfaces of the Tracker↔Core pair and had never run in this pipeline — it needs the Core, another product, which nothing here deployed. The seam was verified by hand or not at all. The first time it ran against a real stack it found three defects invisible to every other suite, two of them product defects, one in each repository.CI now pulls the Core's three service images from GHCR at a pinned SHA (never
latest, so a defect merged in the other repo cannot turn these pull requests red), deploys them with a minimal fixture of this repo's own, runs the full robot suite, and retires the fixture immediately — it is scaffolding for one step, and leaving it standing changes the conditions of every step after.Verified on the runner: 242 passed · 0 failed,
core-integrationincluded.🤖 Generated with Claude Code