Commit graph

12 commits

Author SHA1 Message Date
Brandon Schneider
bd5eaadce9 fix: force production LE CA in Caddy + racknerd TLS deploy script
k3s-edge.nix:
- Added 'ca https://acme-v02.api.letsencrypt.org/directory' to porkbun_tls snippet
- Forces production LE instead of staging

fix-racknerd-tls.sh:
- Checks current Porkbun keys (redacted)
- Verifies production LE CA is configured
- Provides deploy and restart instructions
- Documents how to update Porkbun API keys via sops
2026-05-29 02:07:18 -05:00
Brandon Schneider
a8a163650a fix(infra): resolve k3s services startup issues and update ingress configuration
- Revert builder image in embedded_surface Dockerfile to rust:bookworm for glibc compatibility with bookworm-slim runner.
- Replace racknerd-surface.json Git LFS pointer with the actual retrieved JSON config to resolve parse errors.
- Separated and imported regenerated docker images for stubs and credential-server on all cluster nodes.
- Fixed Ingress resources and middleware to target the correct authentik-server service name.
- Rewrote verification script checks to handle iptables-based ports and relative redirects robustly.
- Updated nixos-laptop IP in node topology documentation.

Build: 0 jobs, 0 errors
2026-05-27 17:39:00 -05:00
Brandon Schneider
f1d9253696 chore(tests): gitignore Playwright test-results and node_modules 2026-05-26 21:12:00 -05:00
Brandon Schneider
7f64942fd2 chore(infra): add internal routing smoke-test script
scripts/verify-internal.sh runs the exact verification sequence before
the edge is touched. Checks (in order):

  0. Port listeners — host Caddy owns :80, Traefik NodePort on :30080
  1. GET / — 200 Homer or 302 → auth.researchstack.info (not internal IP)
  2. /api/* bypass — none of /api/*/health may 302 to Authentik
  3. auth.researchstack.info — 200/302 from Authentik, no internal-IP loop
  4. Host header passthrough — Traefik :30080 /ping reachable; /api/jobs/health
     routes end-to-end through host Caddy → Traefik → Ingress
  5. X-Forwarded-Proto — https header survives the server-Caddy hop

Usage:
  # on nixos-laptop directly:
  bash 4-Infrastructure/k3s-flake/scripts/verify-internal.sh

  # from any tailnet node:
  bash 4-Infrastructure/k3s-flake/scripts/verify-internal.sh --remote

Exit 0 = safe to deploy edge. Exit 1 = fix red checks first.

Generated with Devin (https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-05-26 21:08:58 -05:00
Brandon Schneider
6ca8fd439b feat(k3s-edge): rewrite edge Caddy as dumb TLS forwarder + legacy 301s
Edge Caddy now does exactly three things:
1. Terminate TLS for researchstack.info + *.researchstack.info via
   Porkbun DNS-01 (wildcard cert covers all subdomains in one renewal)
2. 301-redirect legacy subdomains to canonical path equivalents:
     status.*  → /server/status/
     dash.*, home.*  → /
     media.*  → /apps/jellyfin/
     books.*  → /apps/books/
     music.*  → /apps/music/
     vault.*  → /server/vault/
     pulse.*  → /api/registry/
     apps.*  → /apps/
     *.* (wildcard fallback)  → /
3. Forward all other traffic to the internal router (host Caddy :80 on
   k3s-server over Tailscale) with X-Forwarded-* headers preserved.
   auth.* and mail/webmail.* are forwarded unchanged (stable subdomains).

No path routing logic on the edge. Traefik Ingress (k3s-server) owns
all path decisions. This commit has no effect until nixos-rebuild switch
is run on microvm-racknerd (deploy after k3s-server is verified).

Generated with Devin (https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-05-26 21:06:06 -05:00
Brandon Schneider
cfa43cf07f feat(k3s-server): Traefik NodePort + host Caddy pass-through (internal-only)
Port conflict resolution:
- Add HelmChartConfig to pin Traefik web entrypoint to NodePort 30080
  (not host :80) so k3s Traefik and host Caddy do not race for the port
- Add host Caddy on :80 as a minimal pass-through to Traefik :30080;
  carries X-Forwarded-* headers so Traefik sees the real client IP and
  the correct Host. No TLS, no Porkbun, no subdomain logic — all of
  that stays on the edge Caddy (k3s-edge.nix)
- Caddy after= k3s.service so Traefik NodePort is ready before proxying

Authentik port fix:
- Change authentik server + worker services from NodePort 30080 to
  ClusterIP; Traefik reaches Authentik via the rs-auth Ingress and
  cluster DNS, no NodePort required

New manifests (internal, no public-traffic impact):
- manifests/ingress/: Traefik Ingress resources + Middleware CRDs
  (/apps/*, /server/* → forward_auth + strip-prefix; /api/* → strip only;
  / → Homer + forward_auth; auth.* → Authentik, no middleware)
- manifests/hermes/: placeholder chat/orchestrator service
- manifests/credential-server/: token-auth credential vault stub
- manifests/control-plane/: registry-api, jobs-api, blobs-api health stubs
- manifests/homer/configmap.yaml: updated dashboard links to canonical paths

Deploy order: rebuild k3s-server first, verify Traefik + Ingress
internally, then deploy k3s-edge (commit 3 / next step).

Generated with Devin (https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-05-26 21:03:54 -05:00
Brandon Schneider
5f372ea04d test(infra): add Playwright E2E routing test suite
Tests the full traffic path against live researchstack.info infrastructure:
  Edge Caddy (TLS) → Tailscale → Traefik Ingress → k3s services

Coverage:
- edge-tls-redirects: HTTPS reachability, cert validity, legacy subdomain
  301s (status/dash/home/media/books/music/vault/pulse/apps), stable
  subdomains (auth, mail), wildcard fallback
- path-routing: /apps/*, /server/*, /api/* routes; prefix stripping; SSO
  redirect vs token-auth isolation
- auth-integration: Authentik login page, OIDC discovery, forward_auth
  gating on protected paths, /api/* bypass

19/40 tests pass against current live infrastructure (pre-deploy). The 21
failures are "not yet deployed" signals, not design errors. Run after each
phase of the deployment plan to use as a regression gate.

Run: cd 4-Infrastructure/k3s-flake/tests && npm test

Generated with Devin (https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-05-26 21:03:27 -05:00
Brandon Schneider
7eda71868a refactor(rds): consolidate 14 psycopg2 connect patterns into shared rds_connect module
Creates 4-Infrastructure/shim/rds_connect.py with a single connect_rds()
function that resolves connection parameters in priority order:
  1. explicit kwargs
  2. DATABASE_URL env var (postgres://user:pass@host:port/dbname?sslmode=...)
  3. individual RDS_* env vars (RDS_HOST, RDS_PORT, RDS_USER, etc.)
  4. built-in defaults

Auth resolution (when password is empty or RDS_IAM=1):
  1. RDS_IAM_TOKEN env var (pre-computed)
  2. boto3 SDK generate_db_auth_token (preferred)
  3. subprocess aws rds generate-db-auth-token (fallback)
  4. RDS_PASSWORD env var (non-IAM)

Replaces 8 connection pattern variants across 14 active shims:
  - subprocess + RDS_IAM_TOKEN fallback: pist_trace_classify_mcp, joint_classifier,
    pist_prove_and_classify, ingest_57_flexures
  - boto3 SDK: ene_wiki_body_reingest, ene_migrate_and_tag, dataset_ingest_rds
  - subprocess + RDS_PASSWORD: batch_embed_artifacts, sync_wiki_to_rds, seed_flexure_dataset
  - RDS_IAM_AUTH: pist_classify
  - bashrc parsed: credential_loader

v1.4a benchmark confirmed at 100% after refactor.
2026-05-26 15:09:34 -05:00
Brandon Schneider
420bafc0e6 feat(pist): Route-Repair v1.1 — 60 failure flexures ingested, obstruction-type voting 2026-05-26 12:17:42 -05:00
Brandon Schneider
073a70eb86 WIP: accumulated changes 2026-05-25 16:24:21 -05:00
Brandon Schneider
cf0d588291 infra(vps): deploy Authentik, credential vault, age-sops, PQC, ARR plan
- LXC 100: Authentik 2025.4 with PostgreSQL 16 + Redis
- LXC 100: Credential vault HTTP service on port 9100 (PG-backed)
- VPS: Caddy reverse proxy with Let's Encrypt DNS-01 for researchstack.info,
  auth.researchstack.info, vault.researchstack.info
- VPS: Post-quantum SSH (mlkem768x25519-sha256) in sshd_config
- Repo: age-sops secret management enabled
  - Encrypt: .env, restic.env, credentials.json, appflowy.env,
    tailscale-auth.key, porkbun.env, API KEYS/*.txt
  - Add .sops.yaml at repo root and update k3s-flake/.sops.yaml
- Porkbun DNS: update A records to 46.232.249.226, add vault/auth subdomains
- Tailscale: auth key added to credential server (RackNerd microVM)
- Docs: PQC posture, VPS status, Authentik setup guide, ARR stack plan

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-05-20 18:00:11 -05:00
Brandon Schneider
fd863af6fd Expand devcontainer with full Python stack, add MCP servers (Notion/AWS), strengthen Lean theorems
- .devcontainer/Dockerfile: add PostgreSQL client libs, OpenSSL/libffi headers, gfortran/BLAS for scipy, rclone; install full Python dependency set (boto3, psycopg2-binary, fastapi, uvicorn, notion-client, httpx, pytest, numpy, scipy, etc.) in uv-managed venv; add rclone S3 gateway init script as ENTRYPOINT
- .devcontainer/devcontainer.json: switch from build to pre-built image (localhost/research
2026-05-19 01:52:14 -05:00