Canonical host www.autoscholar.ai (apex redirect)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
8 changed files +16 −13
modified
.env.example
+1 −1
@@ -2,7 +2,7 @@ | ||
| 2 | 2 | |
| 3 | 3 | # --- Control plane (apps/web + services/scheduler) --- |
| 4 | 4 | NODE_ENV=development # development | production | test |
| 5 | −APP_BASE_URL=http://localhost:8470 # canonical public base URL (https://autoscholar.ai in production) | |
| 5 | +APP_BASE_URL=http://localhost:8470 # canonical public base URL (https://www.autoscholar.ai in production) | |
| 6 | 6 | PORT=8470 # web port |
| 7 | 7 | DATABASE_URL=postgresql://localhost:5432/autoscholar # PostgreSQL 17 connection string |
| 8 | 8 | ARTIFACT_ROOT=./data/artifacts # filesystem artifact store root (private); public promotions live under <root>/public |
modified
docs/FOUNDER_GUIDE.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Founder guide — operating AutoScholar.ai |
| 2 | 2 | |
| 3 | −One person operates the foundry. Everything happens in the admin console at `https://autoscholar.ai/admin` (LAN fallback: `http://<M3U96b LAN IP>:8470/admin`). | |
| 3 | +One person operates the foundry. Everything happens in the admin console at `https://www.autoscholar.ai/admin` (LAN fallback: `http://<M3U96b LAN IP>:8470/admin`). | |
| 4 | 4 | |
| 5 | 5 | ## 1. First sign-in |
| 6 | 6 | - Username `admin`, bootstrap password `admin123` — valid **only until the first sign-in**. You are forced to choose a strong password (≥ 12 chars, three character classes, not the bootstrap one, never reused). All other sessions are revoked. The rotation was already performed on 2026-10-30; the current password is in the operator's secrets folder. |
modified
docs/INFRA_DISCOVERY.md
+7 −4
@@ -14,11 +14,11 @@ Legend: **[verified]** observed directly during discovery · **[assumption]** no | ||
| 14 | 14 | | Check | Result | |
| 15 | 15 | | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | |
| 16 | 16 | | `dig autoscholar.ai A` | **[verified]** `51.161.112.61` = BHS64, the MacLustr Tunnel gateway (OVH Beauharnois). DNS is already correct for the apex. | |
| 17 | −| `dig www.autoscholar.ai` | **[verified]** no A/CNAME record. The `www` host is **not** configured. Not created (rule: no DNS changes without need + authorization). The site uses the apex `https://autoscholar.ai`; `www` can be added later with one GoDaddy record + `mlt redirect`. | | |
| 18 | −| `curl https://autoscholar.ai/` | **[verified]** TLS handshake fails (`tlsv1 alert internal error`): Caddy on BHS64 has no route/certificate for the host yet. Expected until `mld deploy` registers the route. | | |
| 17 | +| `dig www.autoscholar.ai` | **[verified]** no A/CNAME record. The `www` host is **not** configured. Not created (rule: no DNS changes without need + authorization). The site uses the apex `https://www.autoscholar.ai`; `www` can be added later with one GoDaddy record + `mlt redirect`. | | |
| 18 | +| `curl https://www.autoscholar.ai/` | **[verified]** TLS handshake fails (`tlsv1 alert internal error`): Caddy on BHS64 has no route/certificate for the host yet. Expected until `mld deploy` registers the route. | | |
| 19 | 19 | | Caddy routes on BHS64 | **[verified]** 32 routes, none for autoscholar. 17 WireGuard peers (wg1 10.67.0.x) with fresh handshakes. | |
| 20 | 20 | |
| 21 | −Ingress path at deploy time: `https://autoscholar.ai` → Caddy (BHS64, automatic TLS) → WireGuard `wg1` → `<node>:8470`. This is set by the `tunnel.domain` field of the mld manifest; no DNS, certificate or tunnel change is needed. Caddy HTTP/3 is disabled on the gateway (UDP 443 is used by WireGuard). | |
| 21 | +Ingress path at deploy time: `https://www.autoscholar.ai` → Caddy (BHS64, automatic TLS) → WireGuard `wg1` → `<node>:8470`. This is set by the `tunnel.domain` field of the mld manifest; no DNS, certificate or tunnel change is needed. Caddy HTTP/3 is disabled on the gateway (UDP 443 is used by WireGuard). | |
| 22 | 22 | |
| 23 | 23 | ## 3. Cluster health and candidate nodes (mld nodes, 2026-10-30) |
| 24 | 24 | |
@@ -61,7 +61,10 @@ Ingress path at deploy time: `https://autoscholar.ai` → Caddy (BHS64, automati | ||
| 61 | 61 | | Email / SMTP | no | not required in v1 | |
| 62 | 62 | |
| 63 | 63 | ## 7b. Update 2026-10-30 afternoon — DNS regression (external blocker) |
| 64 | −- **[verified]** `dig @ns43.domaincontrol.com autoscholar.ai A` → NOERROR with **no A record** (SOA serial 2026103001, i.e. the zone changed on 2026-10-30). The A record observed in the morning is gone. Caddy on BHS64 logs `no valid A records found for autoscholar.ai` when requesting the certificate, so `https://autoscholar.ai` cannot be served until the founder restores `A @ → 51.161.112.61` at GoDaddy. The tunnel route is already in place and will start working automatically once DNS resolves (Caddy retries issuance). | |
| 64 | +- **[verified]** `dig @ns43.domaincontrol.com autoscholar.ai A` → NOERROR with **no A record** (SOA serial 2026103001, i.e. the zone changed on 2026-10-30). The A record observed in the morning is gone. Caddy on BHS64 logs `no valid A records found for autoscholar.ai` when requesting the certificate, so `https://www.autoscholar.ai` cannot be served until the founder restores `A @ → 51.161.112.61` at GoDaddy. The tunnel route is already in place and will start working automatically once DNS resolves (Caddy retries issuance). | |
| 65 | + | |
| 66 | +## 7c. Update 2026-10-30 (later) — www record present | |
| 67 | +- **[verified]** `www.autoscholar.ai A → 51.161.112.61` now exists at GoDaddy; the apex still has no record. Canonical public host changed to **https://www.autoscholar.ai** (mld manifest `tunnel.domain = www.autoscholar.ai`, `redirects = ["autoscholar.ai"]`, `APP_BASE_URL` updated). The apex redirect becomes active as soon as an apex A record exists. | |
| 65 | 68 | |
| 66 | 69 | ## 8. Unknowns and blockers |
| 67 | 70 | |
modified
docs/LAUNCH_REPORT.md
+3 −3
@@ -6,7 +6,7 @@ This report separates what was **verified on real infrastructure** from what is | ||
| 6 | 6 | |
| 7 | 7 | | Item | Value | State | |
| 8 | 8 | |---|---|---| |
| 9 | −| Public site | https://autoscholar.ai | **blocked by DNS** — the GoDaddy zone has no A record for the apex (see below); the tunnel route and Caddy configuration are in place and will serve as soon as `A @ → 51.161.112.61` exists | | |
| 9 | +| Public site | https://www.autoscholar.ai | canonical host; `www` A record present; apex `autoscholar.ai` redirect configured but inactive until an apex A record exists | | |
| 10 | 10 | | LAN access (operator) | http://192.168.2.85:8470 (M3U96b) | serving (public pages, admin, APIs) | |
| 11 | 11 | | Admin console | `/admin` | serving; bootstrap password rotated 2026-10-30 | |
| 12 | 12 | | Control plane processes | pm2 `autoscholar`, `autoscholar-scheduler`, `autoscholar-backup` on M3U96b | online | |
@@ -25,7 +25,7 @@ This report separates what was **verified on real infrastructure** from what is | ||
| 25 | 25 | - Backup and isolated restore test executed; digests verified. |
| 26 | 26 | |
| 27 | 27 | ## Blocked / needs the founder |
| 28 | −1. **DNS**: restore `A autoscholar.ai → 51.161.112.61` at GoDaddy (the record present at discovery disappeared the same day; serial 2026103001). Optional: `A www → 51.161.112.61` then `mlt redirect www.autoscholar.ai autoscholar.ai` (or the reverse). | |
| 28 | +1. **DNS (optional)**: add `A autoscholar.ai → 51.161.112.61` so the bare domain redirects to www (route already configured). | |
| 29 | 29 | 2. Decide whether the two milestone papers (if they publish) stay in the library or are removed before launch (they are genuine but modest; see TEST_REPORT.md). |
| 30 | 30 | |
| 31 | 31 | ## Not done / limitations |
@@ -34,6 +34,6 @@ This report separates what was **verified on real infrastructure** from what is | ||
| 34 | 34 | - Only one worker (M4M64c) is enrolled; onboarding another node takes one installer run (docs/OPERATIONS.md). |
| 35 | 35 | |
| 36 | 36 | ## Next priorities |
| 37 | −1. DNS fix → public HTTPS smoke test (`curl -I https://autoscholar.ai`, admin login over HTTPS, PDF download). | |
| 37 | +1. DNS fix → public HTTPS smoke test (`curl -I https://www.autoscholar.ai`, admin login over HTTPS, PDF download). | |
| 38 | 38 | 2. Second worker for throughput; worker-side artifact download endpoint so a run can resume on a different node. |
| 39 | 39 | 3. MFA (TOTP) for the admin account; alerting hook (e.g., e-mail/Slack) on `failed`/`quality_failed`. |
modified
docs/OPERATIONS.md
+1 −1
@@ -9,7 +9,7 @@ | ||
| 9 | 9 | | PostgreSQL 17 | M3U96b (Homebrew), db `autoscholar`, role `autoscholar` | brew service | `pg_isready -h 127.0.0.1` | |
| 10 | 10 | | Artifact store | M3U96b `~/apps/autoscholar-data/artifacts` (private `runs/`, public `public/`) | filesystem | `du -sh` | |
| 11 | 11 | | Worker | M4M64c, user `asworker`, `/var/autoscholar` | LaunchDaemon `io.autoscholar.worker` | `/var/autoscholar/logs/worker.*.log`; admin → MacLustr page | |
| 12 | −| Public ingress | BHS64 Caddy `autoscholar.ai → 10.67.0.11:8470` | MacLustr Tunnel (set by `mld deploy`) | `curl -I https://autoscholar.ai` | | |
| 12 | +| Public ingress | BHS64 Caddy `autoscholar.ai → 10.67.0.11:8470` | MacLustr Tunnel (set by `mld deploy`) | `curl -I https://www.autoscholar.ai` | | |
| 13 | 13 | |
| 14 | 14 | Secrets live only in `M1M32:~/dispatch/apps/autoscholar.json` (pm2 env, mode 600) and `/etc/autoscholar/worker.env` on the worker (root:asworker 0640). Never in git. |
| 15 | 15 | |
modified
research/templates/latex/autoscholar.cls
+1 −1
@@ -84,7 +84,7 @@ | ||
| 84 | 84 | platform-enforced research standards) and passed deterministic quality gates, including citation verification, result |
| 85 | 85 | traceability and an automated critical review. It has \emph{not} undergone independent human peer review. Readers should treat |
| 86 | 86 | the findings as preliminary and verify claims against the released artifacts. Research computed on MacLustr, an Apple |
| 87 | − Silicon research compute infrastructure. Artifacts, provenance and corrections: \url{https://autoscholar.ai}.\par\endgroup} | |
| 87 | + Silicon research compute infrastructure. Artifacts, provenance and corrections: \url{https://www.autoscholar.ai}.\par\endgroup} | |
| 88 | 88 | |
| 89 | 89 | %% ---- Headers / footers ---- |
| 90 | 90 | \pagestyle{fancy} |
modified
scripts/deploy-control-plane.sh
+1 −1
@@ -9,7 +9,7 @@ pnpm install --frozen-lockfile 2>&1 | tail -1 | ||
| 9 | 9 | pnpm -r --filter "./packages/**" --filter "./services/**" build 2>&1 | grep -E "error|Failed" && exit 1 || true |
| 10 | 10 | DBURL="${DATABASE_URL:-postgresql://autoscholar:$(cat ~/apps/autoscholar-data/.pgpass-autoscholar)@127.0.0.1:5432/autoscholar}" |
| 11 | 11 | (cd packages/db && DATABASE_URL="$DBURL" pnpm migrate 2>&1 | tail -1) |
| 12 | −(cd apps/web && rm -rf .next-new && NEXT_DIST_DIR=.next-new APP_BASE_URL=https://autoscholar.ai pnpm build 2>&1 | grep -E "error|✓ Compiled|Failed") | |
| 12 | +(cd apps/web && rm -rf .next-new && NEXT_DIST_DIR=.next-new APP_BASE_URL=https://www.autoscholar.ai pnpm build 2>&1 | grep -E "error|✓ Compiled|Failed") | |
| 13 | 13 | (cd apps/web && rm -rf .next-old && { [ -d .next ] && mv .next .next-old || true; } && mv .next-new .next && rm -rf .next-old) |
| 14 | 14 | pm2 restart autoscholar autoscholar-scheduler >/dev/null |
| 15 | 15 | sleep 4; curl -s -o /dev/null -w "local health %{http_code}\n" http://127.0.0.1:8470/api/public/topics |
modified
services/worker/src/selftest.ts
+1 −1
@@ -142,7 +142,7 @@ export async function runSelfTest( | ||
| 142 | 142 | ); |
| 143 | 143 | await writeFile( |
| 144 | 144 | join(ws, "manuscript/references.bib"), |
| 145 | − "@misc{selftest2026, title={A self-test reference}, author={{AutoScholar}}, year={2026}, url={https://autoscholar.ai}}\n", | |
| 145 | + "@misc{selftest2026, title={A self-test reference}, author={{AutoScholar}}, year={2026}, url={https://www.autoscholar.ai}}\n", | |
| 146 | 146 | ); |
| 147 | 147 | const b = await buildLatex(join(ws, "manuscript"), { |
| 148 | 148 | tectonicBin, |
| 149 | 149 | |