_null confirmed queuenorth.com as the permanent public origin, which settles
#212 and exposed a wrong claim written earlier the same day.
docs/OPERATIONS.md said queuenorth.com "is not this deployment ... do not
diagnose against it". That came from a DNS lookup and an assumption. It is this
deployment: both hostnames serve the identical bundle and this server's own
/api/health shape, 24.41.108.95 is this network's own public IP, and both reach
qn-website-dev on nebula — queuenorth.com through nginx-proxy-manager on
thor/exodus, qn.isnull.dev through Cloudflare. Two front doors, one container,
no non-production environment.
That is the worst direction for a runbook to be wrong in, so the correction
quotes the wrong sentence rather than replacing it silently. The QA Round 0
table likewise gained the production observations as extra rows instead of
having its originals rewritten.
Dockerfile: the CORS_ORIGIN fallback was '*'. The server sets credentials:true
and browsers reject '*' with credentials outright, so that fallback would have
broken every form rather than over-permitting. Now the real origin.
healthcheck.sh and preflight.sh now watch production by default, with the
second front door reachable through their env overrides — the two ingresses
terminate TLS in different places and can rot independently.
Also fills a gap adoption left explicitly undone: the deploy path is a Portainer
stack, id 58 on nebula, found from the container's own compose labels.
OPERATIONS.md documents it, including that the stack file is a separate copy
from this repository's docker-compose.yml and the two have already drifted.
That drift is all that remains of #212 — one trailing slash on line 21 of the
stack file. Left in place: nothing is broken today, and fixing it recreates the
container and takes both front doors down together.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Ten scripts from ~/.openclaw/Projects/Template, taken one at a time and
configured against this deployment rather than copied wholesale.
Configured, not just copied:
- check-env.sh SPEC written from what server/index.js actually reads — 24
variables, each with the consequence of getting it wrong
- secrets.sh plus this project's own shapes: a bare 60+ hex run, which is
how the Zoho WebToLead tokens leaked into four commits, and a
reCAPTCHA key shape as NOTED rather than a failure, because the
site key and the secret key are indistinguishable by shape
- status.sh nebula / qn-website-dev
- healthcheck.sh /api/health, asserting 200 AND "status":"ok" AND "db":"ok".
The template probed /healthz, which does not exist here
- preflight.sh https://qn.isnull.dev, no --auth — there are no accounts
- verify.sh GUARD_DIR=scripts/verify.d, since this project has no test
runner and no typecheck for it to detect
- backup.sh ENGINE block replaced for SQLite: better-sqlite3's online
.backup() inside the container, verified with PRAGMA
integrity_check before anything is renamed into place
- restore-check.sh rewritten rather than configured — the template's is
pg_restore/psql end to end with no seam. Replays the dump from
SQL into a scratch database and times it
Three guards in scripts/verify.d, because verify.sh would otherwise detect
nothing and exit 2: the build, the tracked-tree secret scan, and a check that
every document carries a valid Status, Governs and Review trigger.
Every guard was proven to fail before being trusted, per GUARDS.md rule 1:
healthcheck against a 200 that is not this app, secrets against the real
historical leak replayed out of 033bdf6, doc-headers against both a missing
Review trigger and the Status word "Historical", restore-check against a
truncated dump, an empty database and a raised row floor.
pre-commit is ADAPTED, not the template's. That one runs `npx tsc --noEmit` and
`npx vitest run`; this project has neither, so unchanged it would refuse every
commit. It runs the secret scan and `npm run build`. Hooks are not activated by
this commit — `git config core.hooksPath .githooks` is a separate, per-clone act.
package.json: adds `verify`, and corrects the version to 0.9.3. It said 0.8.3
while the last four commits said batch 0.9.0 through 0.9.3 — the second drift of
the phase-versioning rule, which is retired in the following commit.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>