diff --git a/.gitmodules b/.gitmodules index 1983db97..9ea98fb8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -25,3 +25,6 @@ [submodule "0-Core-Formalism/lean/singer-theorem-lean"] path = 0-Core-Formalism/lean/singer-theorem-lean url = https://github.com/allaunthefox/singer-theorem-lean.git +[submodule "shared-data/precomputed-math-data"] + path = shared-data/precomputed-math-data + url = https://github.com/allaunthefox/precomputed-math-data diff --git a/.mcp.json.full b/.mcp.json.full index 60eb49e3..20dbb3aa 100644 --- a/.mcp.json.full +++ b/.mcp.json.full @@ -64,7 +64,8 @@ "4-Infrastructure/infra/service-orchestrator/service_orchestrator.py" ], "env": { - "AUTHENTIK_BASE": "http://100.102.173.61:9000", + "AUTHENTIK_BASE": "${AUTHENTIK_BASE:-http://100.115.119.40:9000}", + "AUTHENTIK_TOKEN_FILE": "/home/allaun/.config/ene/authentik.token", "CADDY_ADMIN": "http://100.101.247.127:2019", "CREDENTIAL_SERVER": "http://100.101.247.127:8444" } @@ -73,7 +74,10 @@ "_comment": "Authentik SSO MCP server \u2014 user/group/application management via Authentik API v3. Requires AUTHENTIK_TOKEN env var. Built from 4-Infrastructure/shim/authentik_agent_manager/.", "command": "/home/allaun/Research Stack/4-Infrastructure/shim/authentik_agent_manager/target/release/mcp_server", "args": [], - "env": {} + "env": { + "AUTHENTIK_BASE_URL": "${AUTHENTIK_BASE:-http://100.115.119.40:9000}", + "AUTHENTIK_TOKEN_FILE": "/home/allaun/.config/ene/authentik.token" + } }, "contextstream": { "_comment": "Persistent memory, context, and search across all coding sessions. Provides session management, knowledge graph, code search, and decision/lesson capture. Plan: Elite.", diff --git a/4-Infrastructure/AGENTS.md b/4-Infrastructure/AGENTS.md index e4356404..f6ab5f9b 100644 --- a/4-Infrastructure/AGENTS.md +++ b/4-Infrastructure/AGENTS.md @@ -309,7 +309,113 @@ python3 4-Infrastructure/storage/storage_agent.py --loop --interval 900 |------|---------| | `~/.cache/storage-agent.jsonl` | Hash-chained JSONL receipt log | | `~/.cache/storage-agent.log` | Human-readable stdout/stderr from systemd and hook runs | -| `s3://research-stack/agent-receipts/` | Durable S3 receipts (Garage) | +## Authentik SSO Stack: k3s + Helm + Caddy + +Authentik is deployed on `cupfox` (`100.115.119.40`) inside a lightweight single-node `k3s` cluster using Helm, and integrated with the edge Caddy reverse proxies on `racknerd` (`100.80.39.40`). + +### Node configuration (cupfox) + +- **K3s server**: Installed with `--disable traefik --disable servicelb` to conserve memory. +- **Authentik chart**: Deployed into the `authentik` namespace with custom `authentik-values.yaml` secrets. +- **Port forwarding**: Host port `9000` is forwarded to the `authentik-server` NodePort `30080` via `socat` systemd user service (`authentik-port-forward.service`). +- **Firewall**: Port `9000/tcp` allowed on the Tailscale interface. + +### Credentials & Agent Configuration + +- **API Token**: Stored securely at `/home/allaun/.config/ene/authentik.token` (`chmod 600`). +- **Agent updates**: The Python orchestrator (`service_orchestrator.py`, `configure_vault_authentik.py`) and Rust `authentik_agent_manager` support loading the token from the file specified in `AUTHENTIK_TOKEN_FILE` env var. +- **MCP server**: configured in `.mcp.json.full` with: + ```json + "env": { + "AUTHENTIK_BASE_URL": "${AUTHENTIK_BASE:-http://100.115.119.40:9000}", + "AUTHENTIK_TOKEN_FILE": "/home/allaun/.config/ene/authentik.token" + } + ``` + +### Configured Applications & Providers + +All Proxy Providers run in `forward_single` mode, with cookie domain `researchstack.info`, mapped to the embedded outpost (`2540112b-fb26-489d-92da-82ccccef8bbc`): + +| Application | Slug | External Host | Internal Backend | +|-------------|------|---------------|------------------| +| **Research Stack Vaultwarden** | `researchstack-vault` | `https://vault.researchstack.info` | `http://100.115.119.40:8080` | +| **Research Stack Chat** | `research-stack-chat` | `https://chat.researchstack.info` | `http://100.85.244.73:9119` (Steam Deck) | +| **Research Stack Auth** | `research-stack-auth` | `https://auth.researchstack.info` | `http://100.115.119.40:9000` | + +### Caddy Integration (racknerd) + +Edge Caddy on `racknerd` intercepts traffic to protected subdomains and routes authorization checks: +```caddy +forward_auth 100.115.119.40:9000 { + uri /outpost.goauthentik.io/auth/caddy + copy_headers Remote-User Remote-Name Remote-Email X-Authentik-Username X-Authentik-Name X-Authentik-Email +} +``` + +## Fraction Rules + +All numeric thresholds are Q16_16 (UInt32, one = 0x00010000 = 65536). +No Float arithmetic. Threshold constants defined at the top of the file. + +### Q16_16 Fraction Types + +| Type | Description | Use Case | +|------|-------------|----------| +| `Q16_16` | 16.16 fixed-point | General computation | +| `Q0_16` | 0.16 fixed-point | Values in [0, 1) | +| `Q12_20` | 12.20 fixed-point | High precision fractions | +| `Q20_12` | 20.12 fixed-point | Large integer + fraction | + +### Fraction Construction Rules + +1. **Use canonical constructors only** + ```python + Q16_16.ofNat(n) # for integers + Q16_16.ofRatio(a,b) # for rational numbers + Q16_16.ofRawInt(x) # for already-scaled integers + ``` + +2. **Never use `ofFloat` in compute paths** + - Allowed only at external boundary (JSON parsing, sensor input) + - Must be immediately bracketed: `ofFloat(x).toFixedPoint().compute()` + +## Gauge Theory Research Program + +Gauge theory is the most rigorous framework for mapping out math because it forces explicit +distinctions between theorems, conjectures, and empirical observations. Use it as a probe, +not as a claim. + +### What Gauge Theory Demands + +1. **Proven vs Conjectural** + - If you claim a correspondence, you must prove it or label it an ansatz + - Empirical correlations are data, not theorems + - Gauge theory requires: "Is this a theorem or an ansatz?" + +2. **Dimensional Honesty** + - Dimensional mismatches must be explicitly addressed, not papered over + +3. **Category/Type Correctness** + - Frustration is boolean/Z₂ + - Wilson loop is real-valued (trace of holonomy) + - Curvature is Lie-algebra-valued + - Confusing these categories is a type error + +### Recommended Framing + +Use gauge theory as a research program: + +``` +"We investigate whether SilverSight can be derived from lattice gauge theory. +We have proven X, observed Y empirically, and conjecture Z. +Here are the falsification criteria." +``` + +Never claim: + +``` +"SilverSight IS gauge theory" +``` ## Current Stack-Solidification Anchors diff --git a/4-Infrastructure/infra/service-orchestrator/service_orchestrator.py b/4-Infrastructure/infra/service-orchestrator/service_orchestrator.py index 33c9bcd1..576d188f 100644 --- a/4-Infrastructure/infra/service-orchestrator/service_orchestrator.py +++ b/4-Infrastructure/infra/service-orchestrator/service_orchestrator.py @@ -29,6 +29,12 @@ import httpx AUTHENTIK_BASE = os.getenv("AUTHENTIK_BASE", "http://localhost:9000") AUTHENTIK_TOKEN = os.getenv("AUTHENTIK_TOKEN") +if not AUTHENTIK_TOKEN: + token_file = os.getenv("AUTHENTIK_TOKEN_FILE") + if token_file and os.path.exists(token_file): + with open(token_file, "r") as f: + AUTHENTIK_TOKEN = f.read().strip() + CADDY_ADMIN = os.getenv("CADDY_ADMIN", "http://100.101.247.127:2019") CREDENTIAL_SERVER = os.getenv("CREDENTIAL_SERVER", "http://100.101.247.127:8444") AUTHORIZATION_FLOW = os.getenv( diff --git a/4-Infrastructure/shim/authentik_agent_manager/src/bin/mcp_server.rs b/4-Infrastructure/shim/authentik_agent_manager/src/bin/mcp_server.rs index f73c7602..61fa7e14 100644 --- a/4-Infrastructure/shim/authentik_agent_manager/src/bin/mcp_server.rs +++ b/4-Infrastructure/shim/authentik_agent_manager/src/bin/mcp_server.rs @@ -147,8 +147,16 @@ async fn main() -> anyhow::Result<()> { .with_writer(std::io::stderr) .init(); - let token = std::env::var("AUTHENTIK_TOKEN") - .map_err(|_| anyhow::anyhow!("AUTHENTIK_TOKEN environment variable not set"))?; + let token = if let Ok(t) = std::env::var("AUTHENTIK_TOKEN") { + t + } else if let Ok(path) = std::env::var("AUTHENTIK_TOKEN_FILE") { + std::fs::read_to_string(path) + .map_err(|e| anyhow::anyhow!("Failed to read AUTHENTIK_TOKEN_FILE: {}", e))? + .trim() + .to_string() + } else { + anyhow::bail!("AUTHENTIK_TOKEN or AUTHENTIK_TOKEN_FILE environment variable not set"); + }; let base_url = std::env::var("AUTHENTIK_BASE_URL") .unwrap_or_else(|_| "https://researchstack.info".to_string()); diff --git a/4-Infrastructure/shim/authentik_agent_manager/src/main.rs b/4-Infrastructure/shim/authentik_agent_manager/src/main.rs index ddf639e6..864661b6 100644 --- a/4-Infrastructure/shim/authentik_agent_manager/src/main.rs +++ b/4-Infrastructure/shim/authentik_agent_manager/src/main.rs @@ -82,7 +82,7 @@ const DEFAULT_BASE_URL: &str = "https://researchstack.info"; struct Cli { /// Authentik API token (or set AUTHENTIK_TOKEN env var). #[arg(long)] - token: String, + token: Option, /// Authentik base URL. #[arg(long, default_value = DEFAULT_BASE_URL)] @@ -143,16 +143,22 @@ enum Command { async fn main() -> anyhow::Result<()> { tracing_subscriber::fmt::init(); - let mut cli = Cli::parse(); - if cli.token.is_empty() { + let cli = Cli::parse(); + let mut resolved_token = cli.token.clone(); + if resolved_token.is_none() { if let Ok(t) = std::env::var("AUTHENTIK_TOKEN") { - cli.token = t; + resolved_token = Some(t); + } else if let Ok(path) = std::env::var("AUTHENTIK_TOKEN_FILE") { + if let Ok(t) = std::fs::read_to_string(path) { + resolved_token = Some(t.trim().to_string()); + } } } - if cli.token.is_empty() { - anyhow::bail!("Set --token or AUTHENTIK_TOKEN environment variable"); - } - let client = authentik::Client::new(&cli.base_url, &cli.token); + let token = match resolved_token { + Some(t) => t, + None => anyhow::bail!("Set --token, AUTHENTIK_TOKEN, or AUTHENTIK_TOKEN_FILE environment variable"), + }; + let client = authentik::Client::new(&cli.base_url, &token); match cli.cmd { Command::Execute { plan } => { diff --git a/4-Infrastructure/shim/configure_vault_authentik.py b/4-Infrastructure/shim/configure_vault_authentik.py index 536b1535..7f072654 100644 --- a/4-Infrastructure/shim/configure_vault_authentik.py +++ b/4-Infrastructure/shim/configure_vault_authentik.py @@ -4,10 +4,18 @@ import requests import json import sys -TOKEN = os.environ.get("AUTHENTIK_TOKEN", "sLYSgzOsIO0elCJXVtpkYkTDtnkkIoGnu10CdbQxjQa6F7EO3QsRbZC3Pf0Z") +TOKEN = os.environ.get("AUTHENTIK_TOKEN") +if not TOKEN: + token_file = os.environ.get("AUTHENTIK_TOKEN_FILE") + if token_file and os.path.exists(token_file): + with open(token_file, "r") as f: + TOKEN = f.read().strip() +if not TOKEN: + TOKEN = "sLYSgzOsIO0elCJXVtpkYkTDtnkkIoGnu10CdbQxjQa6F7EO3QsRbZC3Pf0Z" BASE_URL = "https://auth.researchstack.info" OUTPOST_UUID = "1ceb9880-517e-4fe6-acb8-ecc1c8276bf4" + headers = { "Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json", diff --git a/shared-data/precomputed-math-data b/shared-data/precomputed-math-data new file mode 160000 index 00000000..cf28838b --- /dev/null +++ b/shared-data/precomputed-math-data @@ -0,0 +1 @@ +Subproject commit cf28838be713b7c93942be80382b43d3b81da898