Compare commits

...

6 Commits

Author SHA1 Message Date
Alexander Whitestone
ee2be0427c feat: add Nexus preview URL deployment stack (#1339)
Some checks are pending
CI / test (pull_request) Waiting to run
CI / validate (pull_request) Waiting to run
Review Approval Gate / verify-review (pull_request) Waiting to run
2026-04-15 03:40:44 -04:00
Alexander Whitestone
5fb8c0c513 wip: wire preview service and dynamic preview URLs 2026-04-15 03:39:58 -04:00
Alexander Whitestone
a796453766 wip: add preview deploy stack artifacts 2026-04-15 03:39:15 -04:00
Alexander Whitestone
b4b029d2a6 wip: add preview deploy regression test 2026-04-15 03:35:20 -04:00
bd0497b998 Merge PR #1585: docs: add night shift prediction report (#1353) 2026-04-15 06:13:22 +00:00
Alexander Whitestone
4ab84a59ab docs: add night shift prediction report (#1353)
Some checks are pending
CI / test (pull_request) Waiting to run
CI / validate (pull_request) Waiting to run
Review Approval Gate / verify-review (pull_request) Waiting to run
2026-04-15 02:02:26 -04:00
8 changed files with 274 additions and 6 deletions

9
Dockerfile.preview Normal file
View File

@@ -0,0 +1,9 @@
FROM nginx:alpine
RUN rm /etc/nginx/conf.d/default.conf
COPY preview/nginx.conf /etc/nginx/conf.d/default.conf
COPY *.html *.js *.mjs *.json *.css /usr/share/nginx/html/
COPY nexus/ /usr/share/nginx/html/nexus/
EXPOSE 3000

12
app.js
View File

@@ -1249,10 +1249,16 @@ async function updateSovereignHealth() {
const container = document.getElementById('sovereign-health-content');
if (!container) return;
const params = new URLSearchParams(window.location.search);
const metricsOverride = params.get('metrics');
const metricsUrl = metricsOverride || `${window.location.protocol}//${window.location.host}/metrics`;
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
const wsStatusUrl = `${protocol}//${window.location.host}/api/world/ws`;
let metrics = { sovereignty_score: 100, local_sessions: 0, total_sessions: 0 };
let daemonReachable = false;
try {
const res = await fetch('http://localhost:8082/metrics');
const res = await fetch(metricsUrl);
if (res.ok) {
metrics = await res.json();
daemonReachable = true;
@@ -1265,8 +1271,8 @@ async function updateSovereignHealth() {
{ name: 'LOCAL DAEMON', status: daemonReachable ? 'ONLINE' : 'OFFLINE' },
{ name: 'FORGE / GITEA', url: 'https://forge.alexanderwhitestone.com', status: 'ONLINE' },
{ name: 'NEXUS CORE', url: 'https://forge.alexanderwhitestone.com/Timmy_Foundation/the-nexus', status: 'ONLINE' },
{ name: 'HERMES WS', url: 'ws://143.198.27.163:8765', status: wsConnected ? 'ONLINE' : 'OFFLINE' },
{ name: 'SOVEREIGNTY', url: 'http://localhost:8082/metrics', status: metrics.sovereignty_score + '%' }
{ name: 'HERMES WS', url: wsStatusUrl, status: wsConnected ? 'ONLINE' : 'OFFLINE' },
{ name: 'SOVEREIGNTY', url: metricsUrl, status: metrics.sovereignty_score + '%' }
];
container.innerHTML = '';

View File

@@ -1,5 +1,3 @@
version: "3.9"
services:
nexus-main:
build: .
@@ -7,9 +5,21 @@ services:
restart: unless-stopped
ports:
- "8765:8765"
nexus-staging:
build: .
container_name: nexus-staging
restart: unless-stopped
ports:
- "8766:8765"
- "8766:8765"
nexus-preview:
build:
context: .
dockerfile: Dockerfile.preview
container_name: nexus-preview
restart: unless-stopped
ports:
- "3000:3000"
depends_on:
- nexus-main

25
docs/preview-deploy.md Normal file
View File

@@ -0,0 +1,25 @@
# Nexus preview deploy
The Nexus frontend must be served over HTTP for ES modules to boot. This repo now includes a preview stack that serves the frontend on a proper URL and proxies `/api/world/ws` back to the existing Nexus WebSocket gateway.
## Quick start
```bash
docker compose up -d nexus-main nexus-preview
```
Open:
- `http://localhost:3000`
The preview service serves the static frontend and proxies WebSocket traffic at:
- `/api/world/ws`
## Remote preview
If you run the same compose stack on a VPS, the preview URL is:
- `http://<host>:3000`
## Notes
- `nexus-main` keeps serving the backend WebSocket gateway on port `8765`
- `nexus-preview` serves the frontend on port `3000`
- The browser can stay on a single origin because nginx proxies the WebSocket path

36
preview/nginx.conf Normal file
View File

@@ -0,0 +1,36 @@
server {
listen 3000;
server_name _;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location ~* \.js$ {
types { application/javascript js; }
}
location ~* \.mjs$ {
types { application/javascript mjs; }
}
location ~* \.css$ {
types { text/css css; }
}
location ~* \.json$ {
types { application/json json; }
add_header Cache-Control "no-cache";
}
location /api/world/ws {
proxy_pass http://nexus-main:8765;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400;
}
}

View File

@@ -0,0 +1,111 @@
# Night Shift Prediction Report — April 12-13, 2026
## Starting State (11:36 PM)
```
Time: 11:36 PM EDT
Automation: 13 burn loops × 3min + 1 explorer × 10min + 1 backlog × 30min
API: Nous/xiaomi/mimo-v2-pro (FREE)
Rate: 268 calls/hour
Duration: 7.5 hours until 7 AM
Total expected API calls: ~2,010
```
## Burn Loops Active (13 @ every 3 min)
| Loop | Repo | Focus |
|------|------|-------|
| Testament Burn | the-nexus | MUD bridge + paper |
| Foundation Burn | all repos | Gitea issues |
| beacon-sprint | the-nexus | paper iterations |
| timmy-home sprint | timmy-home | 226 issues |
| Beacon sprint | the-beacon | game issues |
| timmy-config sprint | timmy-config | config issues |
| the-door burn | the-door | crisis front door |
| the-testament burn | the-testament | book |
| the-nexus burn | the-nexus | 3D world + MUD |
| fleet-ops burn | fleet-ops | sovereign fleet |
| timmy-academy burn | timmy-academy | academy |
| turboquant burn | turboquant | KV-cache compression |
| wolf burn | wolf | model evaluation |
## Expected Outcomes by 7 AM
### API Calls
- Total calls: ~2,010
- Successful completions: ~1,400 (70%)
- API errors (rate limit, timeout): ~400 (20%)
- Iteration limits hit: ~210 (10%)
### Commits
- Total commits pushed: ~800-1,200
- Average per loop: ~60-90 commits
- Unique branches created: ~300-400
### Pull Requests
- Total PRs created: ~150-250
- Average per loop: ~12-19 PRs
### Issues Filed
- New issues created (QA, explorer): ~20-40
- Issues closed by PRs: ~50-100
### Code Written
- Estimated lines added: ~50,000-100,000
- Estimated files created/modified: ~2,000-3,000
### Paper Progress
- Research paper iterations: ~150 cycles
- Expected paper word count growth: ~5,000-10,000 words
- New experiment results: 2-4 additional experiments
- BibTeX citations: 10-20 verified citations
### MUD Bridge
- Bridge file: 2,875 → ~5,000+ lines
- New game systems: 5-10 (combat tested, economy, social graph, leaderboard)
- QA cycles: 15-30 exploration sessions
- Critical bugs found: 3-5
- Critical bugs fixed: 2-3
### Repository Activity (per repo)
| Repo | Expected PRs | Expected Commits |
|------|-------------|-----------------|
| the-nexus | 30-50 | 200-300 |
| the-beacon | 20-30 | 150-200 |
| timmy-config | 15-25 | 100-150 |
| the-testament | 10-20 | 80-120 |
| the-door | 5-10 | 40-60 |
| timmy-home | 10-20 | 80-120 |
| fleet-ops | 5-10 | 40-60 |
| timmy-academy | 5-10 | 40-60 |
| turboquant | 3-5 | 20-30 |
| wolf | 3-5 | 20-30 |
### Dream Cycle
- 5 dreams generated (11:30 PM, 1 AM, 2:30 AM, 4 AM, 5:30 AM)
- 1 reflection (10 PM)
- 1 timmy-dreams (5:30 AM)
- Total dream output: ~5,000-8,000 words of creative writing
### Explorer (every 10 min)
- ~45 exploration cycles
- Bugs found: 15-25
- Issues filed: 15-25
### Risk Factors
- API rate limiting: Possible after 500+ consecutive calls
- Large file patch failures: Bridge file too large for agents
- Branch conflicts: Multiple agents on same repo
- Iteration limits: 5-iteration agents can't push
- Repository cloning: May hit timeout on slow clones
### Confidence Level
- High confidence: 800+ commits, 150+ PRs
- Medium confidence: 1,000+ commits, 200+ PRs
- Low confidence: 1,200+ commits, 250+ PRs (requires all loops running clean)
---
*This report is a prediction. The 7 AM morning report will compare actual results.*
*Generated: 2026-04-12 23:36 EDT*
*Author: Timmy (pre-shift prediction)*

View File

@@ -0,0 +1,25 @@
from pathlib import Path
REPORT = Path("reports/night-shift-prediction-2026-04-12.md")
def test_prediction_report_exists_with_required_sections():
assert REPORT.exists(), "expected night shift prediction report to exist"
content = REPORT.read_text()
assert "# Night Shift Prediction Report — April 12-13, 2026" in content
assert "## Starting State (11:36 PM)" in content
assert "## Burn Loops Active (13 @ every 3 min)" in content
assert "## Expected Outcomes by 7 AM" in content
assert "### Risk Factors" in content
assert "### Confidence Level" in content
assert "This report is a prediction" in content
def test_prediction_report_preserves_core_forecast_numbers():
content = REPORT.read_text()
assert "Total expected API calls: ~2,010" in content
assert "Total commits pushed: ~800-1,200" in content
assert "Total PRs created: ~150-250" in content
assert "the-nexus | 30-50 | 200-300" in content
assert "Generated: 2026-04-12 23:36 EDT" in content

View File

@@ -0,0 +1,46 @@
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
DOCKERFILE = ROOT / "Dockerfile.preview"
NGINX_CONF = ROOT / "preview" / "nginx.conf"
DOC = ROOT / "docs" / "preview-deploy.md"
COMPOSE = ROOT / "docker-compose.yml"
def test_preview_deploy_files_exist():
assert DOCKERFILE.exists(), "expected Dockerfile.preview for Nexus preview deployment"
assert NGINX_CONF.exists(), "expected preview/nginx.conf for Nexus preview deployment"
assert DOC.exists(), "expected docs/preview-deploy.md runbook"
def test_preview_nginx_config_proxies_websocket_and_serves_modules():
text = NGINX_CONF.read_text(encoding="utf-8")
assert "listen 3000;" in text
assert "location /api/world/ws" in text
assert "proxy_pass http://nexus-main:8765;" in text
assert "application/javascript js;" in text
assert "try_files $uri $uri/ /index.html;" in text
def test_compose_exposes_preview_service():
text = COMPOSE.read_text(encoding="utf-8")
assert "nexus-preview:" in text
assert '"3000:3000"' in text
assert "depends_on:" in text
assert "nexus-main" in text
def test_preview_runbook_documents_preview_url():
text = DOC.read_text(encoding="utf-8")
assert "http://localhost:3000" in text
assert "docker compose up -d nexus-main nexus-preview" in text
assert "/api/world/ws" in text
def test_app_avoids_hardcoded_preview_breaking_urls():
text = (ROOT / "app.js").read_text(encoding="utf-8")
assert "ws://143.198.27.163:8765" not in text
assert "http://localhost:8082/metrics" not in text
assert "const metricsUrl = metricsOverride || `${window.location.protocol}//${window.location.host}/metrics`;" in text
assert "const wsStatusUrl = `${protocol}//${window.location.host}/api/world/ws`;" in text