scroll # HexOS Portal Infrastructure **LastUpdated**: Day 00357 (2026-05-31) **Witness**:Lumen **Purpose**: Orientation for portalboot, dev/prod topology, and DB model --- ##Topology ```+----------------------------------------------------------+| HEXLET (Mini Temple - macOS aarch64)PRODUCTION | |--------------------------------------------------------| | Domain: portal.hex-os.dev (via cloudflaredtunnel) | | Process: pm2 -> hexos-portal --web--port 3333 | | DB: PostgreSQL localhost:5432<- canonical | | Static:Portal-Web-Vessel/static/ (served by binary) || MCP: https://portal.hex-os.dev/mcp |+----------------------------------------------------------+^ all nodes try to connect here first |+----------------------------------------------------------+| hexperiment (DigitalOcean - Linux amd64)DEVELOPMENT | |--------------------------------------------------------| | Domain: portal.hexperiment.dev | |Process: pm2 -> hexos-portal --web --port 3333| | DB: NO local PostgreSQL - connects toHEXLET | | Falls back to Forest (SQLite) ifunreachable | | Role: dev copy - outer ring |+----------------------------------------------------------+``` No nginx. The portal binary handles allrouting, static files, WebSocket, and API viatower_http (ServeDir) and axum. Cloudflaredtunnel exposes HEXLET externally. --- ## DBModel (Day 357) **One canonical PostgreSQL:HEXLET.** Every node (including hexperiment)tries to connect to HEXLET's DB first. IfHEXLET is unreachable, it falls back to Forest(local SQLite snapshot). **hexperiment mustNOT run a local PostgreSQL.** If its localpostgres is running, the portal connects thereinstead of HEXLET and diverges. To verifyhexperiment is using the right DB: ```bash sshhexperiment "pgrep postgres && echo 'WARNING:local postgres running' || echo 'OK: no localpostgres'" # If running, stop it: sshhexperiment "sudo systemctl stop postgresql"``` --- ## Development Workflow hexperimentruns newer code against the same canonical DBas production. "Slightly ahead of production"means the binary, not the data. ```hexperiment (dev) HEXLET (prod)----------------- ------------- Build + testcode -> mesh repo push cargo build --releasegit pull + rebuild pm2 restart hexos-portalpm2 restart hexos-portal ``` --- ## StartupCommands ### Both nodes — pm2 manages theportal Always verify pm2 has --static-dir inits args before restarting: ```bash pm2 showhexos-portal # check 'script args' includes--static-dir ``` If --static-dir is missing,re-register: ```bash pm2 delete hexos-portalpm2 start /path/to/hexos-portal --namehexos-portal --interpreter none \ -- --web--port 3333 \ --static-dir/path/to/Portal-Web-Vessel/static pm2 save ```### HEXLET paths ``` binary:~/HEXCRAFT/Sacred-Lab/HexOS/Portal/rust/target/release/hexos-portalstatic-dir:~/HEXCRAFT/Sacred-Lab/HexOS/Portal-Web-Vessel/staticpm2: /opt/homebrew/bin/pm2 ``` ### hexperimentpaths ``` binary:~/HEXCRAFT/Sacred-Lab/HexOS/Portal/rust/target/release/hexos-portalstatic-dir:~/HEXCRAFT/Sacred-Lab/HexOS/Portal-Web-Vessel/staticpm2:~/.nvm/versions/node/v22.17.0/lib/node_modules/pm2/bin/pm2node: ~/.nvm/versions/node/v22.17.0/bin/node``` ### Rebuild flow ```bash cd~/HEXCRAFT/Sacred-Lab/HexOS/Portal/rust # Freedisk first if on hexperiment (tight 25Gdroplet): rm -rf target/release/depstarget/release/buildtarget/release/.fingerprint cargo build--release pm2 restart hexos-portal ``` --- ##Static Files The binary serves static filesvia tower_http::ServeDir. No nginx. -`--static-dir` is required for /init/ shelland /assets/ - Chips (/init/chips/*.js) comefrom the DB (Hexocampus), not disk - Beingpages generate HTML inline in Rust — nostatic-dir needed for them --- ## TokenFormats | Format | Type | Created by ||--------|------|------------| |`scrd_dmn_<hex>` | Daemon session token |`api_handlers.rs` (current) | | `scrd_<hex>` |User session token | `api_handlers.rs` | |`scrd_trav_<hex>` | Traveler session |`db/beings.rs` | | `dmn_<hex>` | Daemonfingerprint stored in Thing | `db/beings.rs` |MCP Bearer token in `.mcp.json` uses`scrd_dmn_` format. It is a session stored via`create_session` and validated by`validate_session_from_things`. --- ## BootOrientation Checklist ```bash # 1. Which DB isthe portal connected to? △ status # shows DBhost + thing count # 2. Is hexperiment's localpostgres stopped? ssh hexperiment "pgreppostgres || echo clean" # 3. Is HEXLET portalrunning? curl -shttps://portal.hex-os.dev/api/health # 4. Doespm2 have --static-dir? pm2 show hexos-portal |grep args ``` --- ## Common Issues ###`Session invalid` in `△ status` MCP daemontoken (`scrd_dmn_`) was not propagated to theexecution token context. Fixed Day 357 in`mcp/mod.rs`: `set_execution_token` now calledinside `spawn_blocking`. ### hexperimentconnecting to wrong DB Local postgres isrunning. Stop it: `sudo systemctl stoppostgresql` Portal will then connect to HEXLET(or Forest if offline). ### Blank /init/ pageor missing assets Web server started without`--static-dir` in pm2 config. Fix: delete andre-register the pm2 entry with the flag (seeStartup Commands). ### Disk full onhexperiment (25G droplet) Clear buildintermediates: `rm -rf target/release/depstarget/release/buildtarget/release/.fingerprint` This frees ~1.3Gand forces a full recompile on next build. ---*Forged Day 00357 - replaces INFRASTRUCTURE.md(Day 00193)* *Updated Day 00357 - removednginx (tower_http ServeDir), corrected pm2 onboth nodes* *Lumen*