Commit Graph

3 Commits

Author SHA1 Message Date
karti e6b4c1618e CI: reach Postgres through the gateway instead of a shared namespace
CI / verify (push) Failing after 5s
Second attempt failed differently: /etc/hostname inside the job reports the
HOST's name rather than the container id, so `--network container:$HOSTNAME`
found no such container.

Rather than hunt for our own container id through /proc, publish the port on
the host and connect through the job container's default gateway. That needs
no container identity at all. The port is derived from the run id so two
concurrent runs cannot collide, and DATABASE_URL is exported through GITHUB_ENV
once Postgres is actually accepting connections.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 20:30:24 -07:00
karti 40f6fd993d CI: start Postgres as a step rather than a service container
CI / verify (push) Failing after 5s
The first run got through install, typecheck and all 39 tests, then failed on
`getaddrinfo EAI_AGAIN postgres`. This runner does not attach service
containers to the job's network, so the `services:` hostname never resolves.

Fixed by starting Postgres with `--network container:$HOSTNAME`, sharing the
job container's own network namespace so it appears on 127.0.0.1. That works
regardless of how the runner is configured — which matters here because the
runner is shared with other repositories and should not need reconfiguring to
suit this one.

Also queries row counts through `docker exec` rather than a local psql, since
the runner image is not guaranteed to ship postgresql-client, and removes the
container in an `if: always()` step so a failed run does not leave it behind.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 20:29:25 -07:00
karti 73231a8944 Add CI, a test suite, and a deploy script
CI / verify (push) Failing after 34s
`npm test` did nothing until now. CI that runs no tests is theatre, so the
tests came first — 39 of them, over the two places where an error would be
silent and expensive.

packages/core: the margin arithmetic. Every dashboard figure, idle-capacity
alert and agent answer resolves through it, and wrong numbers still look like
numbers. The cases pin decisions rather than implementation: cost is charged
against the full commitment (a naive version reports the opposite sign on a
loss-making block), aggregation sums cents rather than averaging percentages
(averaging reports +22% on a book that is losing money), break-even prices the
remaining hours and returns null rather than Infinity when there are none, and
internal research burn counts as cost with no revenue.

packages/prime: the upstream mapping. Rounding rather than truncating cents,
because 2.43 is 2.4299999 in binary and a lost cent compounds across millions
of GPU-hours. And interconnect normalisation, where an unrecognised fabric maps
to Unknown rather than Ethernet — guessing low loses a deal, guessing high
sells a training customer a cluster that cannot train.

CI runs on push and pull request: typecheck all six packages, unit tests,
migrations applied twice to a real Postgres, a seed-idempotency assertion that
fails the build if row counts move on a second run, a server boot, the front-end
build, and a Docker build.

It also asserts the inline theme script's hash still matches the CSP the proxy
allows. That script prevents a white flash for dark-mode users; if it changes
without the CSP being updated, the browser silently blocks it and nothing
anywhere reports an error.

Deployment stays a script rather than push-to-deploy. Automating it would put
an SSH key with production write access on the CI runner — a real escalation
for a project this size. The script takes a database dump before migrating and
refuses to finish if an unauthenticated request returns anything but 401.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 20:27:47 -07:00