Skip to content

feat(ci): nothing was watching whether the ecosystem still holds the contract - #32

Merged
mikim merged 1 commit into
mainfrom
claude/health-conformance-check
Sep 10, 2026
Merged

mikim merged 1 commit into
mainfrom
claude/health-conformance-check

Conversation

@mikim

@mikim mikim commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Why here, and not in each service's repo

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.
  • 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 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. signalmap sat green that way for weeks with an unreadable /api/health.

What it does

Reads statusUrl from ecosystem-registry.json rather than a list of ids, so a service registered tomorrow is covered tomorrow. Probes with a foreign Origin, because a service that reflects only allow-listed origins passes a same-origin curl and still fails every real consumer. No dependencies — urllib only.

Red on: a conformant service regressing · a recorded exception starting to conform, so EXCEPTIONS cannot 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-Control at all: alpha, signal, npc, ao, algora, bridge. The 2026-09-09 nginx session that added ACAO and Vary to eight vhosts did not add this one, and no app sets it either. city is the odd one out — deliberately cached as public, s-maxage=60, stale-while-revalidate=120 by its own Next app.

These ship as recorded EXCEPTIONS rather than failures, because a gate that is red on the day it ships is a gate nobody reads. The fix is one add_header Cache-Control "no-cache" always; per vhost on ssh mossland — worth doing, and worth doing as its own change.

Standing state

7 conformant · 9 known exceptions · 0 unreachable (not graded) · 0 failing

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.mjs leaves the projection byte-identical.

🤖 Generated with Claude Code

…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
mikim merged commit ea80240 into main Sep 10, 2026
9 checks passed
@mikim
mikim deleted the claude/health-conformance-check branch September 10, 2026 04:49
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>
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.

1 participant