feat(ci): nothing was watching whether the ecosystem still holds the contract - #32
Merged
Merged
Conversation
…contract Conformance to HEALTH_CONTRACT.md is mostly not a property of any service's source, so no service's CI can check it. Measured 2026-09-10: passport's own origin at 127.0.0.1:3000 sends no Access-Control-Allow-Origin — the header comes from a hand-edited /etc/caddy/Caddyfile that exists in no repository — and agora's arrives only because an API Gateway CorsConfiguration was deleted from the AWS console. Every service's deploy gate probes an origin *behind* the component that adds the header, so each repo is structurally blind to it. The failure is silent by construction, which is the actual problem. A consumer that cannot read a health endpoint does not go red: monitor.moss.land falls back to city's aggregate and the service keeps a green dot sourced from a probe of an unrelated data URL. signalmap sat green that way for weeks with an unreadable /api/health. So the check belongs where the registry is. It reads statusUrl from ecosystem-registry.json rather than a list of ids, so a service registered tomorrow is covered tomorrow, and probes with a foreign Origin, because a service reflecting only allow-listed origins passes a same-origin curl and still fails every real consumer. Red on: a conformant service regressing; a recorded exception starting to conform, so EXCEPTIONS cannot rot into a list nobody rechecks; or every probe failing, which means the check is broken rather than the ecosystem being down. Not red on: one service being unreachable. This checks the contract, not uptime, and a gate that goes red for an outage is one people learn to ignore. Daily rather than on push — it probes production, and drift here arrives from outside every repository. Also on PRs that touch the registry, the contract or the check itself. FOUND WHILE WRITING IT, and recorded rather than enforced: rule 6 is open across most of the ecosystem. Seven of the sixteen (alpha, signal, npc, ao, algora, bridge, and city differently) send no Cache-Control at all — the 2026-09-09 nginx session that added ACAO and Vary to eight vhosts did not add this one, and no app sets it. city is the odd one, deliberately cached as `public, s-maxage=60, stale-while-revalidate=120` by its own Next app. These ship as EXCEPTIONS because a gate that is red on the day it ships is a gate nobody reads; the fix is one add_header per vhost. Standing state: 7 conformant, 9 recorded exceptions, 0 failing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
mikim
added a commit
that referenced
this pull request
Sep 10, 2026
…33) #32 recorded rule 6 as an exception on seven of sixteen rather than failing the build with it, because a gate that is red on the day it ships is a gate nobody reads. Six are now fixed at the edge, so the entries come out — which the check itself demanded, its exception-rot detector firing on day one. On the box reachable as `ssh mossland`, each `location = /api/health` gained `proxy_hide_header Cache-Control` followed by `add_header Cache-Control "no-cache" always`. signal, npc, ao, algora and bridge already had such a block; alpha had none at all, so one was created. alpha is the careful one. Its vhost is a bare `location /`, and its Access-Control-Allow-Origin comes from the app rather than nginx, so the new block deliberately does not hide or set that header — doing so would delete its only source. It mirrors `location /`'s upstream and forwarding headers, minus the websocket Upgrade/Connection pair, which a plain health GET has no use for. `?strict=1` still lands in it, since nginx location matching ignores the query string; verified live. Each vhost backed up as .bak.rule6.20260910_051009. `nginx -t` clean, and `nginx -T | grep -c rule6` is 0, so the backups are not themselves being served — this box includes `sites-enabled/*` and has been bitten by that before. Every site's `/` still answers as it did. city keeps its rule 6 exception: it is cached on purpose by its own Next app, which makes it an app change in a repo with no local checkout rather than an nginx one. 11 conformant, 4 known exceptions, 0 failing. signalmap is unreachable mid-deploy and is reported rather than graded, which is the case the unreachable branch was written for. 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.
Why here, and not in each service's repo
Conformance to
HEALTH_CONTRACT.mdis mostly not a property of any service's source, so no service's CI can check it. Measured 2026-09-10:passport's own origin at127.0.0.1:3000sends noAccess-Control-Allow-Origin. The header comes from a hand-edited/etc/caddy/Caddyfilethat exists in no repository.agora's arrives only because an API GatewayCorsConfigurationwas deleted from the AWS console.Every service's deploy gate probes an origin behind the component that adds the header, so each repo is structurally blind to this.
The failure is silent, which is the actual problem
A consumer that cannot read a health endpoint does not go red. monitor.moss.land falls back to city's aggregate — which probes an unrelated data URL — and the service keeps its green dot.
signalmapsat green that way for weeks with an unreadable/api/health.What it does
Reads
statusUrlfromecosystem-registry.jsonrather than a list of ids, so a service registered tomorrow is covered tomorrow. Probes with a foreignOrigin, because a service that reflects only allow-listed origins passes a same-origincurland still fails every real consumer. No dependencies —urllibonly.Red on: a conformant service regressing · a recorded exception starting to conform, so
EXCEPTIONScannot rot into a list nobody rechecks · every probe failing, which means the check is broken rather than the ecosystem being down.Not red on: one service being unreachable. This checks the contract, not uptime — a gate that goes red for an outage is one people learn to ignore.
Daily, plus PRs that touch the registry, the contract, or the check itself.
Found while writing it — rule 6 is open across most of the ecosystem
Seven of sixteen send no
Cache-Controlat all:alpha,signal,npc,ao,algora,bridge. The 2026-09-09 nginx session that added ACAO andVaryto eight vhosts did not add this one, and no app sets it either.cityis the odd one out — deliberately cached aspublic, s-maxage=60, stale-while-revalidate=120by its own Next app.These ship as recorded
EXCEPTIONSrather than failures, because a gate that is red on the day it ships is a gate nobody reads. The fix is oneadd_header Cache-Control "no-cache" always;per vhost onssh mossland— worth doing, and worth doing as its own change.Standing state
Related: MosslandOpenDevs/pixel-agent-lab#22 (the reader), MosslandCore/signalmap#134 and MosslandCore/moc-passport#124 (two of the exceptions).
Checks: the check itself passes against live;
node build/generate.mjsleaves the projection byte-identical.🤖 Generated with Claude Code