SPB Git

spb/autoscholar

Public
12.2 KB · 80 lines markdown
1# Infrastructure discovery — AutoScholar.ai on MacLustr23Date: 2026-10-30. Read-only discovery performed from the operator laptop (SSH, `mld`, `mlt`, `dig`, `curl`).4Legend: **[verified]** observed directly during discovery · **[assumption]** not yet verified · **[blocker]** needs founder action.56## 1. Repository and legacy assets78- **[verified]** No AutoScholar repository exists on spbgit (`M1M32:~/srv/git/` has no `*scholar*` repo), none in the `mld` registry, and none under `~/Desktop` on the laptop (the 2026-06 local copy was removed during the 2026-10-02 desktop reorganisation).9- **[verified]** The legacy copy lived on `M1M32:/Volumes/ssd-2to-vv2/v2/autoscholar`; that volume is no longer mounted (only `/Volumes/ssd`, empty). Backup copies were reported on M2M32c and M4BP48 in June 2026; they are **not used, inspected, deleted or migrated** by this build. The legacy product (6 named agents, Vite/Express/SQLite) is not reused in any way.10- **[verified]** This repository (`~/Desktop/Cluster/autoscholar`) is greenfield. First deployment goes through `mld stage` → `mld deploy` → `mld adopt`; afterwards the deployed directory on the node is the git source of truth (`origin` = spbgit `autoscholar.git`), per the MacLustr remote-first rule.1112## 2. Public DNS, TLS and ingress1314| Check                          | Result                                                                                                                                                                                                                                                       |15| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |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://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| Caddy routes on BHS64          | **[verified]** 32 routes, none for autoscholar. 17 WireGuard peers (wg1 10.67.0.x) with fresh handshakes.                                                                                                                                                    |2021Ingress 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).2223## 3. Cluster health and candidate nodes (mld nodes, 2026-10-30)2425- **[verified]** 29 LAN Macs answered `mld nodes` except **M2M32b** (SSH timeout from the laptop at discovery time — hosts the UQO course sites; not needed by AutoScholar, flagged for the operator).26- **[verified]** Control-plane candidate **M3U96b** (Mac Studio M3 Ultra, 28 cores, 96 GB, 79.7 GB free, 454 GB free disk, load 1.8): PostgreSQL 17 listening (scram on TCP; socket access used for provisioning), Redis answering, Node v25.9.0, pm2 (toveli + logrotate only), wg1 peer 10.67.0.11, `claude` CLI 2.1.314, ports 8470–8472 free. Docker CLI present but **daemon not running**.27- **[verified]** Worker candidate **M4M64c** (Mac Studio M4 Max, 16 cores, 64 GB, 372 GB free, macOS 26.4): empty node (no pm2 apps), Node v26.10.0, Python 3.14.7, uv 0.12, Homebrew 7.0.6, `/usr/bin/sandbox-exec` present, `sysadminctl`/`dscl` present, pf available but disabled, only user `simon-pierreboucher` (home `drwxr-x---`), **no Docker, no LaTeX, no `claude` CLI** (the Agent SDK bundles its own binary). Tailscale/wg1 peer present.28- **[verified]** LaTeX is installed on **no** cluster node (no tectonic/pdflatex/latexmk anywhere probed). The laptop has tectonic + MacTeX. → the worker install step installs `tectonic` via Homebrew on the worker node (self-contained, downloads packages on demand).29- **[verified]** Docker Desktop/colima is **not running on any node** (M3U96a/b, M2U64, M4M64a/b probed). Linux-container isolation is therefore not available today; macOS-native isolation is used (see §6 and docs/SECURITY.md).3031## 4. Private control channel (control plane ↔ workers)3233- **[verified]** All nodes share the LAN 192.168.2.0/24 (M3U96b 192.168.2.85, M4M64c 192.168.2.103). The `*.maclustr.io` names resolve to Tailscale 100.x addresses whose ACL blocks inter-node SSH; LAN IPs are the reliable inter-node path (mld discovers them live).34- **Chosen transport**: **worker-initiated outbound HTTPS/HTTP** from the worker node to the control plane's private LAN endpoint (`http://192.168.2.85:8470/api/internal/workers/*`), authenticated with a scoped bearer token issued at enrollment, over the LAN only. Nothing new is exposed on the public gateway except the normal public site; `/api/internal/*` is blocked for requests that arrive through the tunnel (checked on the `X-Forwarded-For`/host layer and by token). No inbound port is opened on the worker.35- **[verified]** Safe health probe of the chosen worker performed: `ssh M4M64c` returned `sw_vers`, memory (68 719 476 736 B), 16 CPUs, disk 372 GB free. SSH is used only for installation and operations by the operator, never by the platform at runtime.3637## 5. Model provider, SDK and authentication3839- **[verified]** `@anthropic-ai/claude-agent-sdk` latest on npm: **0.3.314** (bundles native Claude Code binary `@anthropic-ai/claude-agent-sdk-darwin-arm64`); Claude Code CLI on laptop 2.1.314. Node ≥ 18.14 required.40- **[verified from official docs]** `query()` options used: `cwd`, `settingSources: ['project']` (loads `CLAUDE.md` from the working directory; must be explicit), `systemPrompt` preset `claude_code` + `append`, `permissionMode: 'dontAsk'` (denies anything that would prompt; `canUseTool` never reached), `allowedTools`, `disallowedTools` (scoped rules like `Bash(sudo *)` apply in every mode), `hooks.PreToolUse` (deny beats everything, incl. bypass), `sandbox` (`SandboxSettings`: Seatbelt on macOS, writes limited to cwd, hostname-allowlisted network proxy, `failIfUnavailable`, `allowUnsandboxedCommands: false`), `maxBudgetUsd`, `maxTurns`, `abortController`, `env` (replaces the subprocess environment), `persistSession: false`, `agents` (subagent definitions), `mcpServers` (in-process `createSdkMcpServer`). Result message carries `total_cost_usd`, `modelUsage`, `num_turns`, `duration_ms`, `subtype ∈ {success, error_max_turns, error_max_budget_usd, error_during_execution, …}`.41- **[verified from official docs]** Third-party products must use **API-key authentication** (`ANTHROPIC_API_KEY` in the subprocess env); claude.ai subscription login is not permitted for products. The platform uses the API key only.42- **[verified, presence only]** An Anthropic API key is already provisioned in the cluster (present in the pm2 environment of apps on M3U96a, M3U96b, M4M64a, M4M64b via mld manifests). Its value was not displayed. It will be copied by the operator path (M1M32 manifest → root-owned env file on the worker node) and never committed.43- **[verified]** Laptop shell has no `ANTHROPIC_API_KEY`; local development runs with the key absent (research execution disabled locally, simulated worker for tests only).44- MCP servers `anthropic` and `openalex` configured in Claude Code failed to connect this session; irrelevant to the platform (it uses its own HTTP connectors to Crossref/OpenAlex/arXiv/Semantic Scholar).4546## 6. Isolation primitives available on macOS workers4748- **[verified]** `sysadminctl` + `dscl` (create a dedicated non-admin user), `sandbox-exec`/Seatbelt (used by the Agent SDK sandbox), `pfctl` (per-uid egress rules), `launchd` LaunchDaemon with `UserName` (run the worker as the dedicated user), per-user TCC/POSIX separation (operator home is `drwxr-x---`, Desktop/Documents `drwx------`).49- **[verified]** Sudo on nodes is non-interactive with the documented operator password; used **only** by the operator install scripts, never by the platform.5051## 7. Credentials inventory (presence only)5253| Credential                     | Present?   | Where                                                                                   |54| ------------------------------ | ---------- | --------------------------------------------------------------------------------------- |55| Anthropic API key              | yes        | mld manifests on M1M32 / pm2 envs of 4 nodes (values not read)                          |56| PostgreSQL superuser (M3U96b)  | yes        | local socket on the node (Homebrew install); app role created at provisioning           |57| Object storage (S3)            | **no**     | none in the cluster → filesystem artifact store with checksums (docs/DECISIONS.md D-07) |58| Worker enrollment token        | n/a        | generated by the platform at install                                                    |59| GoDaddy API                    | not needed | DNS already correct                                                                     |60| DOI agency (Crossref/DataCite) | **no**     | DOIs are not issued; UI shows none                                                      |61| Email / SMTP                   | no         | not required in v1                                                                      |6263## 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://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).6566## 7c. Update 2026-10-30 (later) — www record present67- **[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.6869## 8. Unknowns and blockers7071- **[assumption]** The Agent SDK sandbox (`sandbox.enabled`) works under a LaunchDaemon-run non-GUI user on macOS 26.4. Verified in Phase 5 with a real run; `failIfUnavailable: true` makes the worker refuse to run unsandboxed.72- **[assumption]** `tectonic` can fetch its package bundle from the worker node (outbound HTTPS from the node is open; the sandbox allowlist must include the tectonic bundle hosts). Verified in Phase 5.73- No external blocker identified for Phases 0–5. `www.autoscholar.ai` remains unconfigured (needs one GoDaddy A record; founder decision).7475## 9. Chosen architecture (summary; details in docs/DECISIONS.md)7677- Control plane = one mld app `autoscholar` on **M3U96b:8470** (Next.js web + API, plus a `autoscholar-scheduler` pm2 process for leases, retries, QA gates and publication), PostgreSQL 17 database `autoscholar` on the same node, artifact store `~/apps/autoscholar-data` (private) + public promoted artifacts served by the web app.78- Worker = `autoscholar-worker` installed on **M4M64c** under the dedicated user `asworker` (LaunchDaemon), workspaces under `/var/autoscholar/runs/<run-id>`, Claude Agent SDK with sandbox + hooks + budgets, tectonic for LaTeX, uv-managed Python per run.79- Public exposure = existing MacLustr Tunnel route `autoscholar.ai → M3U96b:8470` created by `mld deploy` (no DNS change).80
Files · a78adfcb2b7368f5bc22c4935584f39e3929aa9a
Menu

Theme