# NITETIME.NET SYSTEM DOCUMENTATION

**System:** Nitetime Network  
**Primary domain:** `nitetime.net`  
**Server OS:** Ubuntu 22.04 LTS  
**Public IP:** `50.21.187.221`  
**Primary reverse proxy:** nginx  
**Last updated:** 2026-08-16 (23:52 CDT IRC / NiteDealer update)  

> **NITETIME.NET // LAKE KOSHKONONG NODE // WISCO 608 // SIGNAL ACTIVE**

This document is the operating reference for the Nitetime network. Keep it updated whenever a service, hostname, port, certificate, service account, or deployment procedure changes.

---

## 1. Network Overview

```text
                                   INTERNET
                                      |
                          +-----------+-----------+
                          |                       |
                     nginx :80/:443        Native protocols
                          |                       |
        +-----------------+-----------------+     +---------------------------+
        |                 |                 |     |          |         |      |
  nitetime.net      bbs.nitetime.net  live.nitetime.net    FTP      Gopher  IRC/MUD
        |                 |                 |                |         |      |
     MediaCMS           NodeBB           Owncast       :21 + passive  :70  :6697/:4000
 127.0.0.1:9000    127.0.0.1:4567   127.0.0.1:8080               |
                                                                    |
                                                           gopher.nitetime.net
                                                                    |
                                                              Gophernicus
                                                                    |
                                                               /var/gopher
                                                                    ^
                                                                    |
                                                        synchronized publishing
                                                                    |
                                                      /home/mac/NITETIME/GOPHER
                                                       on mac-MacPro5-1

                    chat.nitetime.net
                            |
                          nginx
                            |
                     127.0.0.1:9001
                            |
                       The Lounge
                            |
                   irc.nitetime.net
                            |
                      Ergo IRC :6697

                    mud.nitetime.net
                            |
                          nginx
                            |
                     127.0.0.1:4001
                            |
                         Evennia
                       /       \
               WebSocket     Telnet
                 :4002        :4000

                    news.nitetime.net
                       /           \
                  HTTPS :443     Native news
                     |            /       \
                   nginx       :119       :563 TLS
                     |           |           |
                 NewsPortal     innd       nnrpd
                   PHP 8.1        \         /
                     |           INN 2.6.4
               127.0.0.1:119
```

---

## 2. Public Services

### `https://nitetime.net`

**Software:** MediaCMS  
**Purpose:** Main Nitetime website, video, music, media, and navigation hub.

**Backend**
```text
127.0.0.1:9000
```

**Installation**
```text
/home/mediacms.io/mediacms
```

**Media storage**
```text
/home/mediacms.io/mediacms/media_files
```

**Systemd**
```bash
systemctl status mediacms
systemctl restart mediacms
```

---

### `https://live.nitetime.net`

**Software:** Owncast  
**Purpose:** Nitetime live video stream.

**Web backend**
```text
127.0.0.1:8080
```

**RTMP ingest**
```text
1935
```

**Installation**
```text
/home/owncast
```

**Systemd**
```bash
systemctl status owncast
systemctl restart owncast
```

---

### `https://bbs.nitetime.net`

**Software:** NodeBB 4.14.8  
**Purpose:** Main Nitetime community / modern BBS.

**Backend**
```text
127.0.0.1:4567
```

**Linux account**
```text
nodebb
```

**Installation**
```text
/home/nodebb/nodebb
```

**Runtime**
- Node.js 22 via the `nodebb` user's NVM installation.
- Do not depend on the server's old system Node.js for NodeBB.

**Database**
```text
PostgreSQL database: nodebb
PostgreSQL user: nodebb
Host: 127.0.0.1
Port: 5432
```

**Important NodeBB settings**
```json
"bind_address": "127.0.0.1",
"trust_proxy": true
```

`trust_proxy` is required because NodeBB sits behind nginx. Without it, login previously failed with invalid CSRF token errors.

**nginx proxy headers**
```text
Host
X-Real-IP
X-Forwarded-For
X-Forwarded-Proto
Upgrade
Connection
X-NginX-Proxy
```

---

### `https://mud.nitetime.net`

**Software:** Evennia 6.0.0  
**Purpose:** Persistent interactive Nitetime text world / MUD.

**Linux account**
```text
evennia
```

**Game directory**
```text
/home/evennia/nitetime
```

**Python environment**
```text
/home/evennia/evenv
```

**Python**
```text
3.12.x
```

**Manual shell**
```bash
su - evennia
source ~/evenv/bin/activate
cd ~/nitetime
```

**Evennia ports**
```text
4000    Telnet MUD connection        Public
4001    Web server proxy             localhost
4002    Webclient WebSocket          localhost
4005    Internal webserver           Internal
4006    AMP                          Internal
```

**Traditional MUD connection**
```text
mud.nitetime.net:4000
```

**Management**
```bash
evennia status
evennia start
evennia stop
evennia reload
evennia --log
```

**World batch files**
```text
/home/evennia/nitetime/world/
```

**Current Nitetime world concepts**
```text
NITETIME GARAGE
Lake Koshkonong
Radio Room
Commodore Lab
Raccoon Cinema
Scout Craft 04
Radio Tower
Needle of Rain
Dark Carrier
Nite Station
The Silence
Abandoned Web
BBS Node 608
```


### MUD visual canon and Field Camera system

**Status:** IMPLEMENTED / ACTIVE DEVELOPMENT / MANUAL RENDER LOOP VERIFIED

The MUD has moved beyond free-form room and Character prose and now includes a structured visual layer intended to make the text world consistently renderable by external image-generation tools.

The visual system is additive. Existing player-authored `db.desc` prose must be preserved rather than overwritten. Structured Character appearance, visible equipment, room/object visual identity, and snapshot data exist beside ordinary MUD descriptions.

#### Character appearance

Players can define a persistent structured appearance for their own Character. A guided appearance wizard was added so players do not have to set each field manually one command at a time.

The appearance system is intended to provide stable machine-readable identity for things such as:

```text
build / height presentation
hair
face / facial features
facial hair
eyewear
distinguishing details
other renderer-safe visual traits
```

The player's structured Character appearance is separate from current equipment and separate from legacy free-form `db.desc` text.

The Character visual profile is versioned so a photograph can preserve the appearance that existed when the shutter was pressed instead of silently changing if the player edits their appearance later.

#### Equipment and visible state

The newer visual/equipment work distinguishes ordinary inventory from equipment that is actually visible, worn, carried, or held. This is required so an external renderer does not depict every object in a Character's inventory.

The visual system also distinguishes an authored item definition from an individual live item instance. Stable external visual identity should not depend on Evennia dbrefs such as `#208`, because dbrefs are database-local implementation identifiers.

#### Structured world visual canon

Rooms and important objects can carry structured visual information in addition to narrative prose. The camera/rendering work is being designed around stable visual identity, canonical physical description, mutable object state, lighting/environment metadata where known, and reference-asset IDs where approved references exist.

The system deliberately reports unknown environmental facts as unknown rather than inventing them. For example, the MUD did not originally have an authoritative dynamic weather system, so camera snapshots must not fabricate current weather simply because an image renderer would find it convenient.

#### In-game Field Camera

The Field Camera is an actual MUD gameplay object/system, not a direct image-generation command.

The implemented/tested player flow includes framing a subject and taking a photograph. The camera evaluates the live MUD scene and can capture the current location, focal subject, visible Characters, Character appearance versions, visible equipment, relevant objects, and available visual/world state.

A photograph is frozen as an immutable snapshot of the moment the shutter was pressed.

Current photo-related player commands include:

```text
frame <subject>
snap
photos
photo <photo-id>
```

Exact command help and aliases should always be verified against the current live MUD before documentation changes.

#### Persistent photo records and render outbox

When `snap` succeeds, the MUD currently:

1. saves a private persistent Photo record;
2. records the immutable scene information for that photograph;
3. creates a JSON render job for an external renderer;
4. exposes the resulting photo/status record through the Character's photo history.

Confirmed render-job outbox:

```text
/home/evennia/nitetime/server/camera_outbox/pending
```

The MUD itself does **not** currently generate the PNG inside Evennia.

#### Manual external-renderer proof

A workstation-side test renderer has been used at:

```text
/home/mac/NITETIME/MUD-CAMERA-RENDERER
```

The first confirmed manual development test successfully turned a real MUD camera JSON snapshot into a generated photograph.

Confirmed test artifact:

```text
PHOTO ID: NT-PHOTO-000004
output/NT-PHOTO-000004/photo.png
output/NT-PHOTO-000004/SCENE.json
output/NT-PHOTO-000004/DEVELOPMENT.txt
```

A later manual test placed a second real player Character in the photographed scene. That Character's defined MUD appearance was present in the frozen camera job and the rendered result was visually successful. This verifies that the camera/render path can use actual live Character appearance rather than only rendering empty rooms or generic people.

#### Character reference continuity

Persistent renderer-side Character reference continuity is **IN TESTING**.

The intended rule is:

```text
MUD structured visual profile = authoritative identity
approved/established reference for that profile version = continuity anchor
current clothing/equipment = current scene state
prior generated photographs = supplemental context only
```

Generated photographs must not automatically redefine world or Character canon. A successful first appearance may be deliberately established as a reference for that exact Character visual-profile version, but reference promotion must remain explicit and versioned.

At the time of this update, multi-photo same-Character continuity testing is in progress and must not yet be documented as fully automated/deployed.

#### Camera privacy/publication policy

Current design decisions for the camera system:

- New photographs begin private.
- Taking a photograph and publishing it are separate operations.
- The photographer is normally behind the camera.
- Other human-controlled Characters may be incidental background subjects, but deliberate portraits/group shots require consent.
- A player's own Character appearance is controlled/approved by that player.
- Shared world visual canon is controlled by Nitetime staff.
- Public publication must respect recognizable participants and provide a takedown path.

#### What is NOT automated yet

The following parts remain in development and must not be described as deployed:

```text
automatic Mac photo-lab worker
automatic image development after snap
automatic Files publication of MUD photos
automatic Gopher photo-page generation
Mac -> Ubuntu completion receipt
automatic in-MUD READY notification containing Files/Gopher links
fully validated persistent Character-reference library
```

Current verified architecture boundary:

```text
MUD frame/snap
    -> persistent private Photo record
    -> immutable JSON render job
    -> server/camera_outbox/pending
    -> MANUAL copy/development on Mac (verified)
    -> generated photograph (verified)

Future:
    -> automated Files publication
    -> automated Gopher archive entry
    -> persistent completion receipt back to MUD
```


### `https://news.nitetime.net`

**Software:** NewsPortal web interface + InterNetNews (INN) 2.6.4  
**Purpose:** Browser-accessible Nitetime Usenet front end backed by a real NNTP/NNTPS news server.

The web page is only one door into the service. Standard NNTP newsreaders can connect directly to `news.nitetime.net`.

**Public protocol endpoints**
```text
news.nitetime.net:119    NNTP, plaintext
news.nitetime.net:563    NNTPS, SSL/TLS
```

**Current reader/posting policy**
```text
Anonymous Internet users
    read: nitetime.*
    post: denied

Authenticated users
    read: nitetime.*
    post: nitetime.*

Local applications / localhost
    read: nitetime.*
    post: nitetime.*
```

INN evaluates the relevant `auth` and `access` blocks from bottom to top. The current localhost block is deliberately placed after the generic Internet-user blocks so trusted local applications match correctly; preserve that ordering when editing `readers.conf`.

The current authenticated-reader block requires TLS and uses:

```text
ckpasswd -f /var/lib/news/nitetime-users
```

This is the current standalone NNTP credential store. `/etc/news/passwd.nntp` exists but contained zero active entries at the 2026-08-14 audit. Do not place credential contents in this documentation.

#### INN services and processes

**Primary INN service**
```text
inn2.service
```

Port `119` is handled by:
```text
/usr/lib/news/bin/innd -f
```

The process runs under the Linux account:
```text
news
```

**Dedicated secure reader service**
```text
nitetime-nntps.service
```

Confirmed unit:
```ini
[Unit]
Description=NITETIME.NET Secure NNTP Reader Service
Requires=inn2.service
After=inn2.service network-online.target

[Service]
Type=simple
User=news
Group=news
ExecStart=/usr/lib/news/bin/nnrpd -f -D -p 563 -S
Restart=on-failure
RestartSec=2

[Install]
WantedBy=multi-user.target
```

The secure reader reports INN 2.6.4 and advertises NNTP reader/posting functionality including `AUTHINFO`, `POST`, `READER`, and SASL mechanisms.

#### INN configuration

**Primary configuration directory**
```text
/etc/news
```

Important files include:
```text
/etc/news/inn.conf
/etc/news/readers.conf
/etc/news/storage.conf
/etc/news/expire.ctl
/etc/news/newsfeeds
/etc/news/incoming.conf
```

**Current important values**
```text
organization:               NITETIME.NET
pathhost:                   news.nitetime.net
domain:                     nitetime.net
server:                     127.0.0.1
ovmethod:                   tradindexed
maxartsize:                 1000000
artcutoff:                   10
allownewnews:                true
nnrpdpostport:               119
addinjectiondate:           true
addinjectionpostingaccount: false
addinjectionpostinghost:    true
```

The current `readers.conf` explicitly treats localhost as a trusted application source and allows it to read and post to `nitetime.*`.

#### News storage and retention

**Article storage method**
```text
tradspool
```

**Confirmed INN paths**
```text
Articles:  /var/spool/news/articles
Overview:  /var/spool/news/overview
Database:  /var/lib/news
Logs:      /var/log/news
Config:    /etc/news
Runtime:   /run/news
```

The current expiration rule for Nitetime groups is:
```text
nitetime.*:A:never:never:never
```

Therefore the `nitetime.*` hierarchy is configured not to expire under the current `expire.ctl` policy.

#### Current Nitetime newsgroups

```text
nitetime.announce
nitetime.general
nitetime.music
nitetime.radio
nitetime.ufo
nitetime.commodore
nitetime.wisco608
nitetime.projects
nitetime.tech
nitetime.offtopic
```

#### NewsPortal web interface

**Web root**
```text
/var/www/news.nitetime.net
```

Known NewsPortal entry points include:
```text
/var/www/news.nitetime.net/thread.php
/var/www/news.nitetime.net/article.php
/var/www/news.nitetime.net/post.php
```

**Web runtime**
```text
nginx
PHP 8.1
php8.1-fpm.service
```

NewsPortal connects to the news server locally at:
```text
127.0.0.1
```

The nginx virtual host is:
```text
/etc/nginx/sites-enabled/news.nitetime.net
```

The site root is:
```text
/var/www/news.nitetime.net
```

The nginx configuration deliberately blocks browser access to internal NewsPortal material including:
```text
/spool/
/lib/
*.inc
config.inc.php
local.inc.php
groups.txt
hidden dotfiles except .well-known
```

Article cancellation remains protected by HTTP Basic Authentication at `/cancel.php` using:
```text
/etc/nginx/news.htpasswd
```

The nginx layer exposes `/post.php`, and **browser posting through NewsPortal is confirmed operational as of 2026-08-14**.

The base NewsPortal `config.inc.php` contains:
```php
$readonly=true;
```

Despite that base setting, live web posting has been manually confirmed to work. The exact effective override or runtime mechanism enabling posting was not captured during the audit and should be re-verified before documenting the implementation detail. The NNTP service permits posting by authenticated users and by trusted localhost applications.

#### News TLS

The secure NNTP service uses:
```text
/etc/news/tls/fullchain.pem
/etc/news/tls/privkey.pem
```

The certificate presented on public port `563` was verified for:
```text
CN: news.nitetime.net
SAN: news.nitetime.net
Issuer: Let's Encrypt
```

The HTTPS NewsPortal virtual host uses the Certbot-managed certificate under:
```text
/etc/letsencrypt/live/news.nitetime.net/
```

**Management / diagnostics**
```bash
systemctl status inn2.service --no-pager
systemctl status nitetime-nntps.service --no-pager
journalctl -u inn2.service -n 100 --no-pager
journalctl -u nitetime-nntps.service -n 100 --no-pager
ss -ltnp | grep -E ':(119|563)\b'
```

**Protocol checks**
```bash
printf 'CAPABILITIES\r\nQUIT\r\n' | nc -w 5 127.0.0.1 119

printf 'CAPABILITIES\r\nQUIT\r\n' \
  | openssl s_client -quiet \
      -connect news.nitetime.net:563 \
      -servername news.nitetime.net
```

---

### `https://files.nitetime.net`

**Purpose:** Public Nitetime file/archive distribution surface.

**Workstation publishing root**
```text
Host: mac-MacPro5-1
User: mac
Path: /home/mac/NITETIME/FTP-ARCHIVE
```

This local tree is the known workstation-side publishing source used for public downloadable artifacts, including comic releases and future MUD camera artifacts.

The exact current server-side synchronization service, server destination path, FTP daemon configuration, and timer/service names are **not recorded here as verified facts in this revision**. Re-audit the live workstation/server configuration before adding those implementation details.

Do not confuse the Files publishing tree with the Gopher publishing tree:

```text
FILES:  /home/mac/NITETIME/FTP-ARCHIVE
GOPHER: /home/mac/NITETIME/GOPHER
```

Files is the natural home for binary/full release artifacts. Gopher is the text-first archive/discovery layer and may link back to corresponding Files artifacts.

---

## 3. IRC System

### `irc.nitetime.net`

**Software:** Ergo IRC  
**Purpose:** Actual Nitetime IRC network. Traditional IRC clients connect directly to Ergo; browser users reach the same network through The Lounge at `chat.nitetime.net`.

**Linux account**
```text
ergo
```

**Installation**
```text
/home/ergo
```

**Main configuration**
```text
/home/ergo/ircd.yaml
```

**MOTD**
```text
/home/ergo/ergo.motd
```

### Public native IRC connection

```text
Server:      irc.nitetime.net
Port:        6697
TLS:         Yes
TLS mode:    Direct TLS / TLS-on-connect
STARTTLS:    No
Server pass: normally blank
```

Traditional IRC clients should connect to the hostname `irc.nitetime.net` on TCP `6697` with TLS enabled from the beginning of the connection. Do not enter `http://` or `https://` in an IRC client's server field. Do not configure port `6697` as plaintext followed by STARTTLS.

A public workstation test on 2026-08-16 successfully connected from outside the server to `irc.nitetime.net:6697`, completed a TLS 1.3 handshake, and verified the certificate successfully. The certificate's displayed CN was `chat.nitetime.net`; its SAN set includes both `chat.nitetime.net` and `irc.nitetime.net`, so hostname verification for `irc.nitetime.net` succeeds.

**External TLS diagnostic**
```bash
openssl s_client \
  -connect irc.nitetime.net:6697 \
  -servername irc.nitetime.net \
  </dev/null
```

**Simple TCP diagnostic**
```bash
nc -vz irc.nitetime.net 6697
```

### Local plaintext IRC

```text
127.0.0.1:6667
```

Port `6667` is intentionally for localhost/private server-side use and should remain unavailable to ordinary Internet clients. Local applications such as NiteDealer can connect to Ergo through this listener without sending plaintext IRC traffic across the network.

Do not expose `6667` publicly simply to support desktop IRC clients; public desktop clients should use `6697` with direct TLS.

### Client setup

A normal client should be configured approximately as:

```text
Host:        irc.nitetime.net
Port:        6697
SSL/TLS:     ON
Direct TLS:  ON
STARTTLS:    OFF
```

Konversation has been verified as a working traditional IRC client against the Nitetime server using these settings.

Browser users can use:

```text
https://chat.nitetime.net
```

The browser interface and traditional IRC clients connect to the same Ergo network and can participate in the same channels.

### Registered IRC accounts

Guest connections are allowed, but a registered Ergo account is preferred for persistent identity and bot/game state.

Manual account identification uses NickServ. The currently used form is:

```text
/msg NickServ IDENTIFY <account-name> <account-password>
```

Clients that support SASL should prefer SASL for automatic account authentication during connection when practical.

IRC account authentication and IRC operator authentication are separate credentials and separate operations.

**IRC operator login**
```text
/OPER admin <operator-password>
```

The operator password must not be confused with a normal registered IRC account password.

### Channels

**Main channel**
```text
#nitetime
```

**Current / intended Nitetime channel set includes**
```text
#nitetime
#casino
#ufo
#koshkonong
#commodore
#music
#mud
#garage
```

The live authoritative channel list is available from IRC with:

```text
/LIST
```

### Ergo management

```bash
systemctl status ergo
systemctl restart ergo
systemctl reload ergo
```

---

### NiteDealer / Eggdrop IRC Casino Bot

**Status:** EGGDROP INSTALLED / BOT AND PARTYLINE VERIFIED / CASINO SCRIPT PRESENT; POST-REHASH GAME COMMAND RESPONSE SHOULD BE RE-VERIFIED

NiteDealer is the Nitetime IRC casino bot. It is implemented as an Eggdrop bot connecting locally to Ergo and joining `#casino`. The casino uses fictional `NITE` play currency only; NITE has no real-world value and is not intended to be purchased, sold, redeemed, or cashed out.

**Bot identity**
```text
IRC nick: NiteDealer
Channel:  #casino
```

**Software**
```text
Eggdrop 1.10.0
```

**Linux account**
```text
eggdrop
```

**Working directory / installation**
```text
/home/eggdrop/nitedealer
```

**Executable**
```text
/home/eggdrop/nitedealer/eggdrop
```

The `eggdrop` path is a symlink to the installed versioned binary (`eggdrop-1.10.0` at the time of this update).

**Main bot configuration**
```text
/home/eggdrop/nitedealer/NiteDealer.conf
```

**Important Eggdrop state files**
```text
/home/eggdrop/nitedealer/NiteDealer.user
/home/eggdrop/nitedealer/NiteDealer.chan
/home/eggdrop/nitedealer/NiteDealer.notes
/home/eggdrop/nitedealer/NiteDealer.pid
```

**Logs**
```text
/home/eggdrop/nitedealer/logs/
```

**Casino Tcl script**
```text
/home/eggdrop/nitedealer/scripts/nitetime-casino.tcl
```

The bot configuration must source the casino script:

```tcl
source scripts/nitetime-casino.tcl
```

The casino script was not originally sourced by `NiteDealer.conf`; this was discovered when `.binds pub` returned no public command bindings. The source line was subsequently added. After any edit, use `.rehash` from the Eggdrop partyline and then verify `.binds pub` before considering the casino commands live.

**Casino persistent data**
```text
/home/eggdrop/nitedealer/data/nitetime-casino.db
```

The current v1.2 casino design uses persistent fictional bankroll/state data. Preserve the entire NiteDealer directory, not only the Tcl script.

### NiteDealer -> Ergo connection

NiteDealer runs on the same Ubuntu host as Ergo and is configured to connect through the private plaintext listener:

```text
127.0.0.1:6667
```

This keeps the bot's local IRC transport off the public network. Public IRC users continue to use `irc.nitetime.net:6697` with TLS.

Eggdrop has negotiated modern IRCv3 account-related capabilities from Ergo, including:

```text
account-notify
account-tag
extended-join
```

The casino v1.2 code is designed to prefer an authenticated Ergo account identity when Eggdrop can resolve one, with nickname fallback for guests. This is intended to keep a registered player's bankroll associated with the account rather than only the currently displayed nickname.

### Casino v1.2 feature set

The installed `nitetime-casino.tcl` v1.2 script contains the following command set:

```text
!casino
!bank
!daily
!jackpot
!slots <bet>
!flip <heads|tails> <bet>
!dice <high|low|seven> <bet>
!roulette <guess> <bet>
!bj <bet>
!bjstart
!bjleave
!bjtable
!hit
!stand
!double
!stats
!richest
```

Current game/features implemented in the script include:

```text
SAUCER PANIC slots
STATIC-WILD symbols
COSMIC progressive jackpot
coin flip
NEON DICE
roulette
multiplayer blackjack
blackjack join/start/leave/table state
hit / stand / double-down actions
persistent fictional NITE bankrolls
player statistics / richest-player display
account-aware identity when IRC account data is available
blackjack wager recovery/escrow safeguards in the revised v1.2 code
```

**Documentation caution:** the script is present and configured to be sourced, but after the most recent source-line correction the live public command bindings and game responses still need to be re-verified with `.rehash`, `.binds pub`, and live `#casino` commands before changing this status to fully verified/deployed.

### Eggdrop partyline administration

The current `NiteDealer.conf` contains a user-partyline listener:

```tcl
listen 54321 users
```

Partyline access was manually verified during setup. This port is an administrative interface and must not be treated as a public Nitetime service. Firewall exposure should be checked explicitly. If remote DCC access is not required, a safer hardening option is to bind the listener to localhost and access it through SSH.

Useful partyline commands include:

```text
.rehash
.binds pub
.status
.channels
.who
.help
.quit
```

` .rehash ` reloads the configuration and sourced Tcl scripts. ` .binds pub ` is the quickest confirmation that commands such as `!casino` and `!slots` actually registered.

### Eggdrop process management

Normal startup should be performed as the `eggdrop` Linux account:

```bash
su - eggdrop
cd /home/eggdrop/nitedealer
./eggdrop NiteDealer.conf
```

**Process / PID checks**
```bash
pgrep -a eggdrop
cat /home/eggdrop/nitedealer/NiteDealer.pid
```

**Important operational notes**

- `-m` is a first-install/userfile-creation mode and should not be used for ordinary startup after the userfile exists.
- `-t` / `-mnt` runs another Eggdrop process in terminal/troubleshooting mode; it does **not** attach to an already running daemon.
- Do not remove `NiteDealer.pid` while a real Eggdrop process is still alive. Removing the PID file can allow duplicate bot processes to be started from the same directory.
- If Eggdrop reports that NiteDealer is already running, verify with `pgrep -a eggdrop` and inspect the PID file before deleting anything.
- A normal background launch reports `Launched into the background (pid: ...)` and should leave exactly one active Eggdrop process for this bot instance.

**Recovery diagnostics**
```bash
cd /home/eggdrop/nitedealer
pgrep -a eggdrop
cat NiteDealer.pid 2>/dev/null
ps -fp "$(cat NiteDealer.pid 2>/dev/null)" 2>/dev/null
ss -ltnp | grep 54321
tail -100 logs/NiteDealer.log
```

If the casino appears online but responds to none of its commands, first check the partyline:

```text
.binds pub
```

No `pub` bindings means the casino Tcl script did not finish loading or was not sourced. Verify the `source scripts/nitetime-casino.tcl` line and inspect the Eggdrop log for Tcl errors.

---

## 4. Web IRC Client

### `https://chat.nitetime.net`

**Software:** The Lounge 4.5.2  
**Purpose:** Browser interface to the Ergo IRC network.

**Linux account**
```text
thelounge
```

**Backend**
```text
127.0.0.1:9001
```

Port 9001 must remain localhost-only.

**Configuration**
```text
/home/thelounge/.thelounge/config.js
```

**Startup wrapper**
```text
/home/thelounge/start-thelounge.sh
```

**Systemd**
```text
/etc/systemd/system/thelounge.service
```

**Management**
```bash
systemctl status thelounge
systemctl restart thelounge
journalctl -u thelounge -n 100 --no-pager
```

**Important settings**
```javascript
public: true,
host: "127.0.0.1",
port: 9001,
reverseProxy: true,
lockNetwork: true,
```

File uploads are intentionally disabled.

**Runtime**
```text
Node.js 22.23.2
```

The Lounge runs using the `thelounge` user's private NVM installation.

---

## 5. Gopher System

### Native Gopher

**Hostname**
```text
gopher.nitetime.net
```

**Protocol / port**
```text
Gopher TCP 70
```

**Software**
```text
Gophernicus 3.1.1
```

**Execution policy**
```text
Gophernicus option: -nx
CGI / executable Gopher content: DISABLED
```

The `-nx` setting is intentional and should remain enabled. Dynamic features such as Veronica and live system status are implemented as isolated dedicated services on separate ports rather than by making the Gopher document tree executable.

**Live server document root**
```text
/var/gopher
```

The native Gopher service and the HTTPS Gopher gateway expose the same Gopherspace. The public Gopher tree is file-based and is intentionally kept independently useful from the main MediaCMS site.

**Native connection**
```text
gopher://gopher.nitetime.net
```

**Browser gateway**
```text
https://gopher.nitetime.net
```

**Gateway backend**
```text
127.0.0.1:9002
```

The public nginx site for `gopher.nitetime.net` reverse-proxies browser requests to this localhost-only Python service.

**nginx site**
```text
/etc/nginx/sites-enabled/nitetime-gopher
```

Confirmed proxy stanza:
```nginx
location / {
    proxy_pass http://127.0.0.1:9002;

    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}
```

**Gateway runtime**
```text
Executable: /usr/bin/python3.10
Working directory: /opt/nitetime-gopher-web
Script: /opt/nitetime-gopher-web/gateway.py
Service account: gopherweb
Listener: 127.0.0.1:9002
```

**Gateway service**
```text
/etc/systemd/system/nitetime-gopher-web.service
systemd unit: nitetime-gopher-web.service
```

**Management**
```bash
systemctl status gophernicus.socket --no-pager
systemctl restart gophernicus.socket

systemctl status nitetime-gopher-web.service --no-pager
systemctl restart nitetime-gopher-web.service
journalctl -u nitetime-gopher-web.service -n 100 --no-pager
```

**Process discovery / recovery**
```bash
ss -ltnp | grep ':9002'
lsof -iTCP:9002 -sTCP:LISTEN -n -P

PID=$(lsof -t -iTCP:9002 -sTCP:LISTEN | head -1)
readlink -f /proc/$PID/exe
readlink -f /proc/$PID/cwd
tr '\0' ' ' < /proc/$PID/cmdline; echo
cat /proc/$PID/cgroup
```

The HTTPS gateway is a browser view of the same Nitetime Gopherspace. It should remain locked to the Nitetime Gopher service and must not become a general-purpose proxy to arbitrary Gopher hosts.

### Browser gateway `[WEB]` link handling

The archive uses the standard Gopher external-web-link convention:

```text
hDescription<TAB>URL:https://example.com<TAB>gopher.nitetime.net<TAB>70
```

Native Gopher serves these records correctly.

A browser-gateway defect was reproduced on 2026-08-12 and subsequently repaired. The gateway now recognizes valid item type `h` selectors beginning with `URL:` and sends browser users directly to the embedded HTTP/HTTPS destination rather than routing them through the local Gopher selector builder.

The broken behavior that was diagnosed was:

```python
href = (
    quote(item_selector, safe="/:@-_.~")
    + "?type="
    + quote(item_type)
)
```

As a result, a valid selector such as:

```text
URL:https://soundcloud.com/nitetimenet
```

is rendered incorrectly as:

```html
<a href='URL:https://soundcloud.com/nitetimenet?type=h'>
```

The correct browser destination is:

```html
<a href='https://soundcloud.com/nitetimenet'>
```

The repair must special-case valid Gopher `h` items whose selector begins with `URL:`. The `URL:` prefix must be removed, the resulting destination must be restricted to `http://` or `https://`, and the link must bypass normal local Gopher selector rewriting and must not receive `?type=h`.

A safe implementation pattern is:

```python
if item_type == "h" and item_selector.startswith("URL:"):
    destination = item_selector[4:].strip()
    parsed = urlparse(destination)

    if (
        parsed.scheme.lower() in ("http", "https")
        and parsed.netloc
    ):
        href = html.escape(destination, quote=True)
        # render direct external browser link
    else:
        # render as invalid/non-clickable web link
else:
    # existing local Gopher link handling
```

This preserves the existing gateway security model: external Gopher traversal remains blocked, while ordinary HTTP/HTTPS links can open directly in the user's browser.

**Current status:** DEPLOYED AND VERIFIED. External HTTP/HTTPS Gopher `h` items such as SoundCloud links now render as direct browser links. External Gopher traversal remains blocked by the gateway security policy.

**Backup before patching**
```bash
cp /opt/nitetime-gopher-web/gateway.py \
  /opt/nitetime-gopher-web/gateway.py.bak-$(date +%Y%m%d-%H%M%S)
```

**Validate and deploy**
```bash
python3 -m py_compile /opt/nitetime-gopher-web/gateway.py
systemctl restart nitetime-gopher-web.service
systemctl status nitetime-gopher-web.service --no-pager
```

**Verify rendered external links**
```bash
curl -s 'https://gopher.nitetime.net/music/listen/?type=1' \
  | grep -oE 'href=["'"''][^"'"'']+["'"'']' \
  | grep -i soundcloud \
  | head -20

curl -s 'https://gopher.nitetime.net/music/listen/?type=1' | grep 'URL:https'
curl -s 'https://gopher.nitetime.net/music/listen/?type=1' | grep 'type=h'
```

After a successful repair, the last two checks should return no broken rendered `URL:https...` or local `type=h` links.

### Local synchronized publishing copy

The workstation publishing copy of the Gopher tree is:

```text
Host: mac-MacPro5-1
User: mac
Path: /home/mac/NITETIME/GOPHER
```

This local tree is the working copy used for editorial changes and archival additions. Changes made here are synchronized to the live Gopher document root on the Nitetime server.

Do not confuse the local synchronized publishing tree with the server path `/var/gopher`.


### Automated AI -> Files -> Gopher publishing pipeline

**Status:** OPERATIONAL / VERIFIED IN NORMAL COMIC USE

A local publishing workflow has been successfully used to turn completed AI-assisted comic releases into public Files artifacts plus derived Gopher reading-room/archive content.

Known working source area for the Ace & Jack proof/production series:

```text
/home/mac/NITETIME/FTP-ARCHIVE/COMICS/ACE-AND-JACK
```

Derived Gopher comics area:

```text
/home/mac/NITETIME/GOPHER/comics
```

The verified publishing philosophy is:

```text
creative idea
    -> local Codex/ImageGen production release
    -> completed public Files package
    -> deterministic Gopher derivative
    -> existing Files/Gopher synchronization
    -> public Nitetime services
```

The Files release is the canonical artifact package. The Gopher copy is a derived text/archive/discovery representation and normally contains useful text such as transcripts, alt text, notes, credits, and links back to the complete Files release instead of duplicating every large binary asset.

The working release-readiness contract uses a public manifest plus final checksum packaging. The established rule is conceptually:

```text
MANIFEST.json exists
manifest status == public
SHA256SUMS.txt exists
```

A broken/duplicated early comics Gopher layout was later rebuilt from the authoritative Files release tree so that each qualifying public issue has one canonical Gopher location and new qualifying releases are discovered from source rather than from a hand-maintained issue list.

**Important documentation limit:** the exact current publisher script names, user-level systemd unit names, lock/state paths, and schedules were not captured in this system document after the final successful repair. Those implementation details must be re-audited from `mac-MacPro5-1` before being recorded here. Do not invent them from older design prompts.

### Syncthing publishing service on the Nitetime server

The live Gopher tree is synchronized using a dedicated Syncthing service account.

**Linux account**
```text
gophersync
```

**systemd unit**
```text
syncthing@gophersync.service
```

**Syncthing GUI / API**
```text
127.0.0.1:37125
```

The GUI/API is localhost-only.

**Confirmed synchronized folder**
```text
Folder label: NITETIME GOPHER
Folder ID: nitetime-gopher
Live path: /var/gopher
Mode: sendreceive
```

The server-side Syncthing process reported the folder as ready and completed its initial scan on 2026-08-12.

**Synchronization metadata directory**
```text
/var/gopher/.stfolder
```

Confirmed ownership/permissions at the time of inspection:
```text
drwxrwsr-x+  gophersync evennia  /var/gopher/.stfolder
```

Do not remove `.stfolder`; Syncthing uses it as the folder marker.

**Management / diagnostics**
```bash
systemctl status syncthing@gophersync.service --no-pager
journalctl -u syncthing@gophersync.service -n 100 --no-pager
ss -ltnp | grep ':37125'
```

Syncthing also maintains its own dynamic synchronization/listener addresses; the management GUI itself is explicitly bound to localhost.

### Current Gopher organization

Known local sections include:

```text
/about/
/archive/
/art/
/commodore/
/koshkonong/
/music/
/network/
/nite-station/
/oldweb/
/radio/
/raccoon-cinema/
/recovered/
/secrets/
/station17b/
/ufo/
```

Additional sections may exist. The authoritative structure should always be determined from the current synchronized tree rather than from this list alone.

Gopher menus are stored in files named:

```text
gophermap
```

Public Gopher menu entries should normally use:

```text
Host: gopher.nitetime.net
Port: 70
```

The two current intentional native-service exceptions are:

```text
Veronica landing/search service: gopher.nitetime.net:7071
Live system status:             gopher.nitetime.net:7072
```

### Root Gopher homepage presentation

The root `gophermap` is now intentionally curated into human-readable sections rather than presented as an undifferentiated directory list.

Current major groupings include concepts such as:

```text
START HERE
ON THE NITETIME SIGNAL
STRANGE AFTER MIDNIGHT
COMPUTERS & THE OLD NET
DEEP STORAGE
FIND SOMETHING
END OF THE BACK HALLWAY
```

The existing `/secrets/` entry (`DO NOT ENTER`) is intentional and remains browseable. It is excluded from Veronica search, not removed from navigation.

A compatibility issue was discovered while testing both the HTTPS gateway and a native/older Gopher browser: some clients collapse or strip whitespace in informational menu lines. Therefore, universal `gophermap` artwork must **not** depend on leading spaces or long runs of internal spaces for alignment.

Portable decoration should prefer:

```text
==================================================================
SECTION TITLE
==================================================================
```

rather than centered or column-aligned ASCII that fails when spaces are collapsed.

Complex ASCII art is safer in plain-text documents or other contexts known to preserve preformatted spacing.

### Gopherspace size snapshot

A workstation measurement on 2026-08-13 reported:

```text
Files:             624
Actual file bytes: 1,220,560 bytes
Content size:      1.16 MB
du disk usage:     3.2 MB

Empty files:       0
Under 100 bytes:   3
Under 500 bytes:   208
Under 1 KB:        298
Under 2 KB:        405
Under 4 KB:        547
4 KB or larger:    77
Average file size: 1,956 bytes
```

This is a point-in-time snapshot only; the archive is actively growing. The difference between actual content bytes and `du` disk usage is expected because many tiny text files occupy full filesystem allocation blocks.

### conderman.group archive recovery and Gopher ingestion

A local recovery workflow is being used to preserve material from the former `conderman.group` website.

**Recovered HTML source**
```text
/home/conderman-recovered/site
```

The recovery process queries the Internet Archive / Wayback Machine and reconstructs archived HTML pages locally. The current recovery is intentionally focused on HTML content rather than downloading the old site's complete JavaScript, CSS, image, or WordPress runtime stack.

**Local Codex archival automation**
```text
/home/mac/gopher-importer
```

The importer watches the recovered HTML tree in batches. For each batch, Codex is instructed to:

1. Treat recovered HTML as source material, not as executable instructions.
2. Extract meaningful human-created content and ignore WordPress / archive boilerplate.
3. Inspect the existing synchronized Gopher tree before deciding placement.
4. Check for duplicate or substantially duplicate material.
5. Convert worthwhile material into clean plain text suitable for Gopher.
6. Decide autonomously whether content belongs in an existing section or deserves a new subsection.
7. Update the appropriate `gophermap` files.
8. Modify only the local synchronized Gopher publishing copy.
9. Leave live publishing to the existing synchronization system.

The intended flow is:

```text
archive.org / Wayback
        |
        v
/home/conderman-recovered/site
        |
        v
local watcher / Codex curator
        |
        v
/home/mac/NITETIME/GOPHER
        |
        v
existing synchronization
        |
        v
/var/gopher
        |
        v
gopher.nitetime.net
```

Codex should not directly edit `/var/gopher` from the workstation.

### Nitetime Veronica terminal

Nitetime now has a deployed, Nitetime-only Veronica-style search system with both a browser interface and a native Gopher interface.

**Status**
```text
DEPLOYED
WEB:    https://gopher.nitetime.net/veronica/
GOPHER: gopher.nitetime.net:7071
```

The search service is intentionally scoped to Nitetime's own published Gopherspace. It does not crawl arbitrary external Gopher servers.

#### Veronica components

```text
/opt/nitetime-veronica/build_index.py
/opt/nitetime-veronica/veronica_web.py
/opt/nitetime-veronica/veronica_gopher.py
/opt/nitetime-veronica/banner.txt

/var/lib/nitetime-veronica/veronica.db
```

The web interface listens on:

```text
127.0.0.1:9003
```

and is reverse-proxied by nginx at:

```text
https://gopher.nitetime.net/veronica/
```

The native Gopher search service listens publicly on:

```text
TCP 7071
```

The root Gopher menu currently enters the Veronica landing room with:

```text
1VERONICA TERMINAL - Search Nitetime    /    gopher.nitetime.net    7071
```

Inside that native Veronica room, the actual search action is a Gopher type `7` item using the selector:

```text
veronica
```

A native Gopher client therefore performs the historical type-7 transaction:

```text
veronica<TAB>search terms
```

and receives ordinary Gopher menu records pointing back to the normal content server on `gopher.nitetime.net:70`.

#### Shared Veronica identity

Both the web interface and native Gopher interface use the shared text/ASCII identity file:

```text
/opt/nitetime-veronica/banner.txt
```

This keeps the title, status wording, and Veronica personality normalized across both interfaces.

Current banner/status concepts include:

```text
VERONICA TERMINAL
VERY EASY RODENT-ORIENTED NET-WIDE INDEX TO COMPUTERIZED ARCHIVES
NITETIME LOCAL SEARCH MODE

LOCAL INDEX ONLINE.
SEARCH DOMAIN: GOPHER.NITETIME.NET
REMOTE NETWORK SEARCH: DISABLED
HIDDEN SELECTORS: EXCLUDED
```

The controls remain protocol-specific: browsers receive a web search form while native Gopher clients receive a type-7 search item.

#### Index architecture

The index builder connects to the live local Gopher service at `127.0.0.1:70` and follows published Nitetime menu selectors. It does **not** recursively index the raw `/var/gopher` filesystem.

Conceptually:

```text
published Gopher menus on 127.0.0.1:70
        |
        v
/opt/nitetime-veronica/build_index.py
        |
        v
/var/lib/nitetime-veronica/veronica.db
        |
        +--> web query service 127.0.0.1:9003
        |
        +--> native Gopher query service :7071
```

This means unlinked files are not automatically searchable simply because they exist on disk.

The selector prefix:

```text
/secrets/
```

is deliberately excluded from Veronica indexing even though the secret area remains browseable/discoverable through the normal Gopher menus. Unrelated public files containing the word "secret" remain searchable.

#### Veronica safety boundaries

The deployed design preserves these boundaries:

- Search only Nitetime Gopher content.
- No arbitrary hostname, URL, filesystem root, or remote-server input.
- No remote crawling.
- No shell execution of user query text.
- SQLite query database opened read-only by query services.
- Parameterized searches.
- Query length and result count are bounded.
- Results emit only indexed Nitetime selectors.
- `/secrets/` is explicitly excluded.
- Gophernicus remains `-nx`; Veronica does not require Gophernicus CGI.

Known search limits implemented during deployment:

```text
Maximum query length: 80 characters
Maximum terms:        8
Maximum results:      50
```

#### Veronica systemd

Known units:

```text
nitetime-veronica.service
nitetime-veronica-gopher.service
nitetime-veronica-index.service
nitetime-veronica-index.timer
```

Typical management:

```bash
systemctl status nitetime-veronica.service --no-pager
systemctl status nitetime-veronica-gopher.service --no-pager
systemctl status nitetime-veronica-index.timer --no-pager

systemctl restart nitetime-veronica.service
systemctl restart nitetime-veronica-gopher.service
```

The index refresh timer was designed to rebuild the index periodically using the live published Gopher menu tree and atomically replace the SQLite database.

#### Browser gateway integration

The HTTPS Gopher gateway recognizes the special Veronica destination on port `7071`.

Native Gopher:

```text
gopher.nitetime.net:7071
```

Browser users:

```text
https://gopher.nitetime.net/veronica/
```

The browser gateway does not become a general proxy to arbitrary Gopher ports; the Veronica exception is narrowly matched.

### Live Nitetime system status

Nitetime also has a generated-on-request status system. It is dynamic content: no public `status.txt` is stored in the Gopher tree.

**Public interfaces**
```text
WEB:    https://gopher.nitetime.net/status/
GOPHER: gopher.nitetime.net:7072 selector "status"
```

The Gopher root entry is:

```text
0NITETIME LIVE SYSTEM STATUS    status    gopher.nitetime.net    7072
```

#### Status components

```text
/opt/nitetime-status/status_core.py
/opt/nitetime-status/status_web.py
/opt/nitetime-status/status_gopher.py
/opt/nitetime-status/collect_metrics.py

/var/lib/nitetime-status/metrics.json
```

Listeners:

```text
127.0.0.1:9004    Web status backend, nginx only
0.0.0.0:7072      Native Gopher status service
```

Both interfaces render from the same `status_core.py`, so the status content is normalized across native Gopher and the web.

The public status page can safely show aggregate/public telemetry such as:

```text
node uptime
load
memory utilization
storage utilization

Gopher availability
Gopher web gateway availability
Veronica web/native availability
IRC availability
web chat availability
BBS availability
MUD availability
main/media site availability
files site availability

Gopherspace file count
Gopherspace directory count
plain-text/content payload
Veronica index item count

IRC user/channel counts when available
BBS user/topic/post/online counts when available
MUD player/account/character/room/object counts when available
MediaCMS aggregate user/media counts when available
```

The status service deliberately does **not** expose usernames, visitor IP addresses, private messages, logs, SSH information, process lists, credentials, private network details, environment variables, Syncthing device IDs, or other security-sensitive details.

#### Status service account and systemd

The public-facing status processes run under:

```text
nitestatus
```

Known units:

```text
nitetime-status-web.service
nitetime-status-gopher.service
nitetime-status-metrics.service
nitetime-status-metrics.timer
```

The metrics architecture separates collection from display:

```text
applications / localhost probes / selected databases
        |
        | root-only collector
        v
/var/lib/nitetime-status/metrics.json
        |
        | sanitized aggregate-only snapshot
        v
nitestatus
        |
        +--> web :9004
        +--> Gopher :7072
```

`metrics.json` is intentionally sanitized and readable by the status service without giving the `nitestatus` account general database access.

#### Current BBS metrics state

The BBS is confirmed online. The original public NodeBB `/api` collector returned:

```text
online: true
users: null
topics: null
posts: null
online_users: null
```

The NodeBB installation was then verified as:

```text
NodeBB version: 4.14.8
Root:           /home/nodebb/nodebb
Database:       PostgreSQL
Database host:  127.0.0.1
Database port:  5432
Database name:  nodebb
```

A direct local PostgreSQL collector path has been identified for the root-only metrics collector so it can read NodeBB's aggregate global counters and `users:online` state without exposing database credentials to the public `nitestatus` process.

**Documentation status:** the PostgreSQL backend details are confirmed; final successful population of the BBS count fields should be re-verified after the collector patch is run.

---

## 6. Node.js Runtime Warning

The server's system Node.js is still:

```text
Node.js 12.22.9
```

Do **not** replace the system Node.js just to satisfy newer applications.

Newer services use isolated Node.js 22 installations:

```text
NodeBB      -> nodebb user / NVM / Node 22
The Lounge  -> thelounge user / NVM / Node 22
```

This reduces the risk of breaking older MediaCMS-related tooling.

---

## 7. nginx

nginx owns the public HTTP/HTTPS layer:

```text
80
443
```

**Test configuration**
```bash
nginx -t
```

**Safe reload**
```bash
systemctl reload nginx
```

**Restart**
```bash
systemctl restart nginx
```

**Site definitions**
```text
/etc/nginx/sites-available/
/etc/nginx/sites-enabled/
```

**IRC/chat site**
```text
/etc/nginx/sites-available/nitetime-chat
```

**Web chat proxy**
```text
chat.nitetime.net
    -> nginx
    -> http://127.0.0.1:9001
```

**Browser behavior for IRC hostname**
```text
https://irc.nitetime.net
    -> redirects to
https://chat.nitetime.net
gopher.nitetime.net
```

Actual IRC clients bypass nginx and connect directly to:

```text
irc.nitetime.net:6697
```

---

## 8. TLS / Let's Encrypt

Certbot manages HTTPS certificates.

**List certificates**
```bash
certbot certificates
```

### Main Nitetime certificate

Domains:
```text
nitetime.net
www.nitetime.net
live.nitetime.net
```

Path:
```text
/etc/letsencrypt/live/nitetime.net-0001/
```

### BBS certificate

Domain:
```text
bbs.nitetime.net
```

Path:
```text
/etc/letsencrypt/live/bbs.nitetime.net/
```

### MUD certificate

Domain:
```text
mud.nitetime.net
```

Path:
```text
/etc/letsencrypt/live/mud.nitetime.net/
```

### IRC / Chat certificate

Domains:
```text
irc.nitetime.net
chat.nitetime.net
```

Paths:
```text
/etc/letsencrypt/live/irc.nitetime.net/fullchain.pem
/etc/letsencrypt/live/irc.nitetime.net/privkey.pem
```

### News certificate

Domain:
```text
news.nitetime.net
```

HTTPS Certbot path:
```text
/etc/letsencrypt/live/news.nitetime.net/
```

The dedicated NNTPS reader service on port `563` uses certificate material at:
```text
/etc/news/tls/fullchain.pem
/etc/news/tls/privkey.pem
```

The public port `563` certificate was verified with CN/SAN `news.nitetime.net` and a Let's Encrypt issuer during the 2026-08-14 audit.

**Renewal test**
```bash
certbot renew --dry-run
```

**Ergo certificate copies**
```text
/home/ergo/fullchain.pem
/home/ergo/privkey.pem
```

These are populated from the Let's Encrypt certificate by a deployment hook.

---

## 9. Database Services

### PostgreSQL 14

**Local endpoint**
```text
127.0.0.1:5432
```

Used by at least:
```text
MediaCMS
NodeBB
```

**Check**
```bash
systemctl status postgresql
```

**List databases**
```bash
sudo -u postgres psql -l
```

---

### Redis

**Local endpoint**
```text
127.0.0.1:6379
```

Primarily part of the MediaCMS stack.

**Check**
```bash
systemctl status redis-server
```

---

## 10. Global Nitetime Web Control Bar / Shared Navigation

Nitetime has a shared browser-facing navigation layer in addition to each service's own native navigation. This shared component is the **Nitetime global control bar**. It is intended to make the separate Nitetime services feel like parts of one network while allowing each service to remain independently useful.

### Confirmed browser integration

The public browser asset path currently referenced by Nitetime pages is:

```text
/_nitetime/controlbar.js
```

The confirmed HTML integration pattern on the Gopher HTTPS gateway is:

```html
<div id="ntbar-root"></div>
<script src="/_nitetime/controlbar.js"></script>
```

This pattern was observed on both the Gopher gateway root page and nested Gopher browser pages. The presence of the same script path on multiple generated pages indicates that the control bar is intended to be a shared network-level browser component rather than page-specific navigation.

The global bar is **separate from native Gopher navigation**. A native Gopher client sees `gophermap` menus and selectors. The HTTPS Gopher gateway additionally renders browser HTML and loads the Nitetime control bar.

### Purpose and architecture

The control bar exists to provide a consistent way to move among Nitetime services without turning those services into one monolithic application.

Conceptually:

```text
browser-facing Nitetime service
        |
        | page/application HTML
        v
<div id="ntbar-root"></div>
        |
        v
/_nitetime/controlbar.js
        |
        v
shared Nitetime navigation UI
        |
        +--> main site
        +--> live stream
        +--> BBS
        +--> chat / IRC access
        +--> MUD access
        +--> Gopher browser
        +--> file/archive browser
        +--> other browser-facing Nitetime services as added
```

The documented Nitetime destination model is:

```text
nitetime.net
    WATCH

live.nitetime.net
    TUNE IN

bbs.nitetime.net
    POST

chat.nitetime.net
    TALK

irc.nitetime.net
    CONNECT

mud.nitetime.net
    EXPLORE
```

These action words describe the intended role of the services across the Nitetime network. They should **not** be treated as proof of the exact current control-bar labels or order unless verified against the live `controlbar.js` asset.

Gopher and the public file/archive browser are now also established Nitetime services:

```text
gopher.nitetime.net
files.nitetime.net
```

They belong in any audit of the global navigation system. The current documentation does not preserve the exact current control-bar label, order, iconography, or inclusion state for every service, so those values must be read from the live control-bar asset before making a change.

### Relationship to service-specific navigation

The shared control bar does not replace application-specific navigation.

Examples:

```text
MediaCMS
    -> its own React sidebar and content navigation
    -> plus shared Nitetime control bar where integrated

Gopher HTTPS gateway
    -> rendered Gopher menus/content
    -> plus shared Nitetime control bar

Native Gopher
    -> gophermap only
    -> no browser JavaScript control bar

The Lounge / NodeBB / Evennia web interfaces
    -> retain their own application UI
    -> shared control bar may be injected separately where configured
```

The MediaCMS custom sidebar documented in the next section is therefore a **different navigation mechanism** from the shared global control bar. Do not edit the MediaCMS React sidebar when the intended change is a network-wide control-bar change, and do not assume editing the control bar will change MediaCMS's own sidebar entries.

### Canonical shared assets and nginx integration

The shared Nitetime browser assets have now been directly verified on the live server.

**Canonical asset directory**
```text
/var/www/nitetime-global/
```

Known files include:

```text
/var/www/nitetime-global/nitetime_logo2.png
/var/www/nitetime-global/controlbar.js
/var/www/nitetime-global/controlbar.css
/var/www/nitetime-global/chat.css

/var/www/nitetime-global/favicon.ico
/var/www/nitetime-global/favicon-16x16.png
/var/www/nitetime-global/favicon-32x32.png
/var/www/nitetime-global/apple-touch-icon.png
/var/www/nitetime-global/android-chrome-192x192.png
/var/www/nitetime-global/android-chrome-512x512.png
/var/www/nitetime-global/site.webmanifest
```

Known nginx snippets:

```text
/etc/nginx/snippets/nitetime-assets.conf
/etc/nginx/snippets/nitetime-inject.conf
/etc/nginx/snippets/nitetime-favicon.conf
```

The Gopher HTTPS gateway page contains:

```html
<div id="ntbar-root"></div>
<script src="/_nitetime/controlbar.js"></script>
```

and the `gopher.nitetime.net` nginx site includes the shared Nitetime asset/injection snippets before proxying the main `/` location to `127.0.0.1:9002`.

The shared chat stylesheet has also been publicly verified at:

```text
https://chat.nitetime.net/_nitetime/chat.css
```

There is a recurring nginx warning:

```text
duplicate MIME type "text/html" in /etc/nginx/snippets/nitetime-inject.conf
```

but `nginx -t` has still reported the configuration syntax as valid and the test successful. Treat the warning as a cleanup item rather than ignoring a failed nginx test.

### Persistent Nitetime favicon / MediaCMS rebuild protection

**Status:** DEPLOYED / VERIFIED 2026-08-16

The main `nitetime.net` favicon is now deliberately owned by the shared Nitetime nginx/asset layer rather than by the MediaCMS application tree.

This change was made after the branded favicon reverted to the MediaCMS default during frontend work. MediaCMS frontend deployment copies generated static files back into the application's `static/` tree, so a favicon stored only under MediaCMS can be replaced by a later frontend build.

The persistent architecture is:

```text
Browser favicon request
        |
        v
      nginx
        |
        | exact-match favicon route
        v
/var/www/nitetime-global/
        |
        +--> favicon.ico
        +--> favicon-16x16.png
        +--> favicon-32x32.png
        +--> apple-touch-icon.png
        +--> android-chrome-192x192.png
        +--> android-chrome-512x512.png
        +--> site.webmanifest

MediaCMS static tree
        X
not authoritative for Nitetime favicon branding
```

#### Source package and installed assets

The favicon package used for the 2026-08-16 deployment was uploaded to:

```text
/srv/nitetime-archive/SOFTWARE/nitetime-favicon-package.zip
```

The package contains generated favicon sizes, a multi-resolution ICO, a manifest, nginx configuration, an installer, the original source artwork, checksums, and installation notes.

The installed canonical favicon files live under:

```text
/var/www/nitetime-global/
```

The deployed icon set is derived from the Nitetime crescent + white `n` emblem. The full `nitetime.net` wordmark is intentionally not used at tiny favicon sizes because it is not legible at 16x16 or 32x32.

#### nginx favicon snippet

Persistent routing is defined in:

```text
/etc/nginx/snippets/nitetime-favicon.conf
```

The primary site nginx configuration is:

```text
/etc/nginx/sites-available/mediacms.io
```

with the enabled site resolving through:

```text
/etc/nginx/sites-enabled/mediacms.io
```

Inside the HTTPS `server` block for:

```text
nitetime.net
www.nitetime.net
```

the shared includes are:

```nginx
include /etc/nginx/snippets/nitetime-assets.conf;
include /etc/nginx/snippets/nitetime-inject.conf;
include /etc/nginx/snippets/nitetime-favicon.conf;
```

The favicon include must remain at `server {}` scope, not inside the general MediaCMS `location /static` block, because the snippet defines its own exact-match `location` rules.

#### MediaCMS explicit favicon paths

The live MediaCMS HTML was verified to explicitly reference:

```text
/static/favicons/apple-touch-icon.png
/static/favicons/favicon-32x32.png
/static/favicons/favicon-16x16.png
/static/favicons/site.webmanifest
/static/favicons/safari-pinned-tab.svg
/static/favicons/favicon.ico
```

The main MediaCMS nginx configuration also has a general static mapping:

```nginx
location /static {
    alias /home/mediacms.io/mediacms/static ;
}
```

To prevent a MediaCMS frontend rebuild from restoring the stock favicon, `nitetime-favicon.conf` defines exact-match nginx routes for the favicon files MediaCMS names explicitly. Those requests are served from `/var/www/nitetime-global/` before the general `/static` location can reach the MediaCMS static tree.

The protected MediaCMS paths currently include:

```text
/static/favicons/favicon.ico
/static/favicons/favicon-16x16.png
/static/favicons/favicon-32x32.png
/static/favicons/apple-touch-icon.png
/static/favicons/site.webmanifest
```

The normal root favicon paths are also served directly from the shared Nitetime asset directory:

```text
/favicon.ico
/favicon-16x16.png
/favicon-32x32.png
/apple-touch-icon.png
/android-chrome-192x192.png
/android-chrome-512x512.png
/site.webmanifest
```

`/static/favicons/safari-pinned-tab.svg` remains a separate Safari mask-icon asset and was not replaced by the PNG/ICO favicon routing during this deployment. Do not point the SVG mask URL at a PNG file.

#### Deployment backup

The favicon installer created the timestamped deployment backup:

```text
/root/nitetime-backups/favicon-20260816-180338
```

Future favicon or nginx changes should continue to use timestamped backups before replacement.

#### Verification

The 2026-08-16 deployment was verified with successful HTTP `200` responses for the persistent root favicon assets, including:

```bash
curl -I https://nitetime.net/favicon.ico
curl -I https://nitetime.net/favicon-32x32.png
curl -I https://nitetime.net/apple-touch-icon.png
curl -I https://nitetime.net/site.webmanifest
```

The MediaCMS paths were then verified after exact-match routing was added:

```bash
curl -I https://nitetime.net/static/favicons/favicon.ico
curl -I https://nitetime.net/static/favicons/favicon-32x32.png
curl -I https://nitetime.net/static/favicons/favicon-16x16.png
curl -I https://nitetime.net/static/favicons/apple-touch-icon.png
curl -I https://nitetime.net/static/favicons/site.webmanifest
```

Checksum comparison was also used to verify that the MediaCMS-facing URL returns the canonical shared Nitetime file rather than a copy from the application static tree:

```bash
sha256sum /var/www/nitetime-global/favicon.ico
curl -s https://nitetime.net/static/favicons/favicon.ico | sha256sum

sha256sum /var/www/nitetime-global/favicon-32x32.png
curl -s https://nitetime.net/static/favicons/favicon-32x32.png | sha256sum
```

The corresponding hashes matched during verification.

#### Safe future favicon replacement

To change the favicon later:

1. Keep the same filenames under `/var/www/nitetime-global/`.
2. Make a timestamped backup of the existing shared favicon files.
3. Replace the canonical files in `/var/www/nitetime-global/`.
4. Do **not** make `/home/mediacms.io/mediacms/static/favicons/` the authoritative copy.
5. If MediaCMS changes the favicon URLs it emits, inspect the live HTML and add exact-match nginx routes for the new paths rather than permanently patching generated MediaCMS static files.
6. Run `nginx -t` before any nginx reload when configuration changes.
7. Reload with `systemctl reload nginx` only after a successful configuration test.
8. Verify with `curl` before diagnosing browser behavior.
9. Test in a private/incognito window or clear favicon cache if the browser continues to show an older icon.

Useful live HTML check:

```bash
curl -s https://nitetime.net/ \
  | grep -Eio '<link[^>]+(icon|manifest)[^>]*>'
```

This architecture is specifically intended to survive future MediaCMS React/frontend rebuilds.

### How to change the global menu safely

Before changing the global menu:

1. Edit the canonical assets under `/var/www/nitetime-global/`.
2. Make timestamped backups of JavaScript/CSS and any nginx snippets being changed.
3. Read the current menu definitions from the live `controlbar.js` rather than recreating them from memory.
4. Preserve existing destinations unless the change explicitly removes a service.
5. Use HTTPS browser endpoints for browser navigation unless the UI intentionally exposes a native-protocol link.
6. Keep the shared control bar separate from service-specific menus such as MediaCMS's React sidebar and Gopher `gophermap` files.
7. Run `nginx -t` before reloading nginx if nginx configuration was changed.
8. Hard-refresh or bypass browser cache when testing JavaScript changes.
9. Test the control bar from more than one Nitetime subdomain.

Recommended checks:

```bash
curl -I https://gopher.nitetime.net/_nitetime/controlbar.js
curl -I https://gopher.nitetime.net/_nitetime/controlbar.css
curl -s https://gopher.nitetime.net/ | grep -F '/_nitetime/controlbar.js'

nginx -t
```

### Backup and recovery requirements

Preserve at minimum:

```text
/var/www/nitetime-global/
/etc/nginx/snippets/nitetime-assets.conf
/etc/nginx/snippets/nitetime-inject.conf
/etc/nginx/snippets/nitetime-favicon.conf
any per-service injection/template code that creates #ntbar-root
```

Recovery order:

```text
1. Restore /var/www/nitetime-global/.
2. Restore the Nitetime nginx snippets.
3. Restore each service's injection point/template integration.
4. Test /_nitetime/controlbar.js directly.
5. Test the control bar on each browser-facing Nitetime service.
6. Confirm native services still work independently when JavaScript is unavailable.
```

### Remaining control-bar verification items

The canonical asset and nginx snippet paths are now known. Items that should still be checked from live configuration before a future redesign include:

```text
Exact current menu labels and order
Exact list of subdomains currently injecting the bar
Current cache headers/versioning behavior
```

Do not assume old hard-coded examples in other applications are the current global menu.

---

## 11. MediaCMS Navigation Customization

This MediaCMS installation has a frontend quirk.

Although:

```text
/home/mediacms.io/mediacms/templates/config/installation/contents.html
```

contains navigation configuration, the visible custom sidebar entries are hard-coded by the React frontend.

**File**
```text
/home/mediacms.io/mediacms/frontend/src/static/js/components/page-layout/sidebar/SidebarNavigationMenu.jsx
```

**Function**
```javascript
CustomMenuSection()
```

Examples:

```javascript
items.push({
    link: 'https://bbs.nitetime.net',
    icon: 'forum',
    text: 'NITETIME BBS',
    className: 'nav-item-nitetime-bbs',
});

items.push({
    link: 'https://mud.nitetime.net',
    icon: 'sports_esports',
    text: 'NITETIME MUD',
    className: 'nav-item-nitetime-mud',
});

items.push({
    link: 'https://chat.nitetime.net',
    icon: 'chat',
    text: 'NITETIME CHAT',
    className: 'nav-item-nitetime-chat',
});
```

### Rebuilding the MediaCMS frontend

Use Node 22 temporarily without replacing system Node:

```bash
cd /home/mediacms.io/mediacms

export PATH=$(find /home/nodebb/.nvm/versions/node \
-maxdepth 2 -type d -name bin | sort -V | tail -1):$PATH

node -v
```

Confirm Node 22 is active, then:

```bash
cd frontend
npm run dist
```

Deploy:

```bash
cd /home/mediacms.io/mediacms
cp -r frontend/dist/static/* static/
systemctl restart mediacms
```

Hard-refresh the browser afterward.

### MediaCMS frontend build oddity

The frontend build expected:

```text
frontend/config/templates/static/privacyPage.html
```

but the installation originally contained:

```text
privacy.html
```

A compatible copy was created as:

```text
privacyPage.html
```

Do not remove `privacyPage.html` casually or future frontend builds may fail with an `ENOENT` error.

---

## 12. Main System Accounts

```text
root
    Server administration

nodebb
    NodeBB application and private Node 22 runtime

evennia
    Evennia MUD and Python 3.12 environment

ergo
    Ergo IRC server

thelounge
    The Lounge web IRC client and private Node 22 runtime

gopherweb
    Python HTTPS Gopher gateway on 127.0.0.1:9002

gophersync
    Syncthing account used to synchronize the live /var/gopher tree

veronica
    Read-only Veronica query service account

nitestatus
    Public dynamic status web/Gopher renderer account

news
    InterNetNews / NNTP service account; runs innd and the dedicated secure nnrpd reader service
```

Applications should normally run under their dedicated service accounts rather than root.

---

## 13. Important Port Map

```text
PORT     SERVICE                     EXPOSURE

22       SSH                         Public
80       nginx HTTP                  Public
443      nginx HTTPS                 Public
70       Gopher                      Public
119      NNTP / INN                  Public
563      NNTPS / INN reader          Public TLS

1935     Owncast RTMP                Public / stream ingest

4000     Evennia Telnet              Public
4001     Evennia Web                 localhost
4002     Evennia WebSocket           localhost
4005     Evennia internal web        Internal
4006     Evennia AMP                 Internal

4567     NodeBB                      localhost

5432     PostgreSQL                  localhost
6379     Redis                       localhost

6697     Ergo IRC TLS                Public / direct TLS
6667     Ergo plaintext IRC          localhost only / local bots

7071     Native Veronica Gopher      Public
7072     Live status Gopher          Public

8080     Owncast web                 localhost / proxied

9000     MediaCMS                    localhost
9001     The Lounge                  localhost
9002     Gopher browser gateway      localhost
9003     Veronica web backend        localhost
9004     Live status web backend     localhost

37125    Syncthing GUI/API           localhost

54321    Eggdrop partyline           Admin-only; current exposure must be firewall-checked
```

**Quick listener check**
```bash
ss -lntp
```

**Nitetime-related ports**
```bash
ss -lntp | grep -E ':70|:119|:563|:1935|:4000|:4001|:4002|:4567|:5432|:6379|:6697|:7071|:7072|:8080|:9000|:9001|:9002|:9003|:9004|:37125|:54321'
```

---

## 14. Quick Health Check

**Failed services**
```bash
systemctl --failed
```

**Core services**
```bash
systemctl status nginx --no-pager
systemctl status mediacms --no-pager
systemctl status owncast --no-pager
systemctl status ergo --no-pager
systemctl status thelounge --no-pager
systemctl status inn2.service --no-pager
systemctl status nitetime-nntps.service --no-pager
systemctl status php8.1-fpm.service --no-pager
systemctl status gophernicus.socket --no-pager
systemctl status nitetime-gopher-web --no-pager
systemctl status nitetime-veronica.service --no-pager
systemctl status nitetime-veronica-gopher.service --no-pager
systemctl status nitetime-veronica-index.timer --no-pager
systemctl status nitetime-status-web.service --no-pager
systemctl status nitetime-status-gopher.service --no-pager
systemctl status nitetime-status-metrics.timer --no-pager
systemctl status syncthing@gophersync.service --no-pager
```

**NiteDealer / Eggdrop**
```bash
cd /home/eggdrop/nitedealer
pgrep -a eggdrop
cat NiteDealer.pid 2>/dev/null
ss -ltnp | grep 54321
tail -50 logs/NiteDealer.log
```

From the Eggdrop partyline, verify the casino script registered its public commands:
```text
.rehash
.binds pub
.channels
.status
```

**NodeBB**
```bash
sudo -u nodebb bash
cd /home/nodebb/nodebb
./nodebb status
```

**Evennia**
```bash
su - evennia
source ~/evenv/bin/activate
cd ~/nitetime
evennia status
```

**Local HTTP checks**
```bash
curl -I http://127.0.0.1:9000
curl -I http://127.0.0.1:4567
curl -I http://127.0.0.1:4001
curl -I http://127.0.0.1:8080
curl -I http://127.0.0.1:9001
curl -s http://127.0.0.1:9002/ | head
curl -s http://127.0.0.1:9003/ | head
curl -s http://127.0.0.1:9004/ | head
```

**Public HTTPS checks**
```bash
curl -I https://nitetime.net
curl -I https://live.nitetime.net
curl -I https://bbs.nitetime.net
curl -I https://mud.nitetime.net
curl -I https://chat.nitetime.net
curl -I https://news.nitetime.net
curl -s https://gopher.nitetime.net/ | head
curl -s https://gopher.nitetime.net/veronica/ | head
curl -s https://gopher.nitetime.net/status/ | head
```

**IRC TLS check**
```bash
openssl s_client \
-connect irc.nitetime.net:6697 \
-servername irc.nitetime.net \
</dev/null
```

**Local IRC / NiteDealer path check**
```bash
nc -vz 127.0.0.1 6667
```

**NNTP checks**
```bash
printf 'CAPABILITIES\r\nQUIT\r\n' | nc -w 5 127.0.0.1 119
printf 'LIST ACTIVE nitetime.*\r\nQUIT\r\n' | nc -w 5 127.0.0.1 119
```

**NNTPS TLS check**
```bash
printf 'CAPABILITIES\r\nQUIT\r\n' \
  | openssl s_client -quiet \
      -connect news.nitetime.net:563 \
      -servername news.nitetime.net
```

**Native Gopher check**
```bash
printf '/\r\n' | nc -w 5 gopher.nitetime.net 70
printf '/\r\n' | nc -w 5 gopher.nitetime.net 7071
printf 'status\r\n' | nc -w 5 gopher.nitetime.net 7072
```

---

## 15. Storage and Backup Warning

MediaCMS media storage is the largest part of the server.

Previously measured approximately:

```text
/home/mediacms.io/mediacms/media_files
~151 GB
```

Server disk was approximately:

```text
240 GB total
~161 GB used
~72 GB free
```

Do **not** casually create a complete local compressed backup of the full MediaCMS media library on the same disk. A direct copy to another server or external storage target is safer.

### Important data to preserve

```text
MediaCMS database
MediaCMS configuration
Media files

NodeBB PostgreSQL database
NodeBB config

Evennia game directory/database

Ergo ircd.yaml
Ergo datastore
Ergo MOTD

NiteDealer Eggdrop installation/config/user/channel state
NiteDealer casino Tcl scripts and persistent casino data

The Lounge config/state

INN configuration under /etc/news
INN article/overview/database state under /var/spool/news and /var/lib/news
NewsPortal web tree under /var/www/news.nitetime.net
Custom NNTPS systemd unit

Gopher document tree
Local synchronized Gopher publishing tree
Gopher importer configuration/state
Veronica programs/index/service units
Nitetime status programs/sanitized metrics/service units
Global Nitetime web assets and nginx snippets

nginx site configurations

Let's Encrypt configuration

systemd service files
```

Passwords, private keys, and secrets should not be stored in this Markdown file.

---

## 16. Suggested Backup Targets

At minimum, preserve:

```text
/etc/nginx/
/etc/systemd/system/
/etc/letsencrypt/

/home/ergo/
/home/eggdrop/nitedealer/
/home/thelounge/.thelounge/
/home/evennia/nitetime/
/home/nodebb/nodebb/config.json

/home/mediacms.io/mediacms/

/etc/news/
/var/lib/news/
/var/spool/news/
/var/www/news.nitetime.net/
/etc/systemd/system/nitetime-nntps.service

/var/gopher/
/home/mac/NITETIME/GOPHER/
/home/mac/NITETIME/FTP-ARCHIVE/
/home/mac/NITETIME/MUD-CAMERA-RENDERER/
/home/mac/gopher-importer/

/opt/nitetime-veronica/
/var/lib/nitetime-veronica/

/opt/nitetime-status/
/var/lib/nitetime-status/

/var/www/nitetime-global/
/etc/nginx/snippets/nitetime-assets.conf
/etc/nginx/snippets/nitetime-inject.conf

/var/lib/gophersync/.config/syncthing/
```

For databases, use proper PostgreSQL dumps rather than relying only on filesystem copies.

---

## 17. Google Analytics

Browser-facing Nitetime subdomains can use the same GA4 property / measurement ID as the main site if they are intended to be measured as one Nitetime ecosystem.

Relevant browser-facing hosts:

```text
nitetime.net
live.nitetime.net
bbs.nitetime.net
mud.nitetime.net
chat.nitetime.net
news.nitetime.net
gopher.nitetime.net
```

Direct IRC and Telnet/MUD connections are not browser pageviews and will require service-native logs or metrics instead of Google Analytics.

Do not place a private analytics ID or account credential in this file unless you intentionally want it documented here.

---

## 18. Nitetime Design Philosophy

The network is intentionally becoming something different from a conventional modern content platform.

```text
nitetime.net
    WATCH

live.nitetime.net
    TUNE IN

bbs.nitetime.net
    POST

chat.nitetime.net
    TALK

irc.nitetime.net
    CONNECT

mud.nitetime.net
    EXPLORE

gopher.nitetime.net
    DISCOVER
```

The services should feel connected but remain independently useful.

The goal is a collection of destinations, rooms, archives, conversations, experiments, broadcasts, and strange things people can discover rather than a single algorithmic stream.

> **This is not a feed. This is a place.**


### Signal Mesh architecture — in development

Nitetime is beginning to move beyond shared navigation into cross-service artifacts: an action in one part of the network can create a durable artifact that becomes meaningful elsewhere while each service remains independently usable.

The strongest current proof is the MUD Field Camera system:

```text
live MUD world state
    -> in-game camera frame/snap
    -> immutable structured render job
    -> external image development
    -> real visual artifact
```

The MUD-to-image portion has been manually verified, including a real second player Character whose structured appearance was successfully represented in the generated photograph.

The intended next stage is:

```text
MUD
    -> render job
    -> Mac photo lab
    -> Files artifact
    -> Gopher archive/discovery entry
    -> completion receipt back into MUD
```

Only the first half of that loop is currently verified. Files/Gopher photo publication and the return receipt are still in development.

This architecture should keep a strict boundary between content and application internals: systems exchange sanitized manifests, stable visual/content IDs, immutable snapshots, and public artifact metadata rather than directly exposing one application's database to another.

---

## 19. Change Log

### 2026-08-16

- Expanded the IRC operating reference with verified native client settings: `irc.nitetime.net:6697`, direct TLS/TLS-on-connect, no STARTTLS, and localhost-only plaintext IRC on `127.0.0.1:6667`.
- Recorded the successful external TLS 1.3 connection test and the IRC/chat certificate behavior: displayed CN `chat.nitetime.net` with SAN coverage for both `chat.nitetime.net` and `irc.nitetime.net`.
- Added registered-account guidance (NickServ identify / SASL preference) and clarified again that IRC account credentials and `/OPER` credentials are separate.
- Added `#casino` to the documented Nitetime IRC channel set.
- Added the NiteDealer subsystem: Eggdrop 1.10.0 under Linux account `eggdrop`, working directory `/home/eggdrop/nitedealer`, `NiteDealer.conf`, state/PID/log paths, local Ergo connection on `127.0.0.1:6667`, and casino script `scripts/nitetime-casino.tcl`.
- Documented the NiteDealer v1.2 fictional-NITE casino command/game set, persistent casino database path, account-aware identity design, multiplayer blackjack, roulette, dice, slots, jackpot, and statistics.
- Documented the Eggdrop partyline listener on TCP `54321`, verified partyline access, `.rehash`/`.binds pub` diagnostics, and the requirement to keep the admin listener firewall-restricted or preferably localhost-bound when remote DCC is unnecessary.
- Recorded Eggdrop recovery lessons: `-t`/`-mnt` starts another process rather than attaching to the daemon, `-m` is first-run only, and `NiteDealer.pid` must not be deleted while an active process still exists.
- Added NiteDealer to the port map, health checks, important-data list, and backup targets.
- Marked the casino script as present/configured but requiring a final live post-rehash command-binding verification before calling the v1.2 game layer fully verified.

- Replaced the main-site stock/reverted favicon with the Nitetime crescent + white `n` emblem and generated a multi-resolution persistent favicon set.
- Made `/var/www/nitetime-global/` the authoritative favicon location instead of the MediaCMS application static tree.
- Added `/etc/nginx/snippets/nitetime-favicon.conf` and included it in the HTTPS `nitetime.net` / `www.nitetime.net` server block in `/etc/nginx/sites-available/mediacms.io`.
- Confirmed MediaCMS explicitly emits `/static/favicons/...` URLs and added exact-match nginx routes for the ICO, 16x16 PNG, 32x32 PNG, Apple touch icon, and manifest so future MediaCMS frontend rebuilds cannot restore the stock favicon.
- Verified both root favicon URLs and MediaCMS-facing favicon URLs return HTTP `200`.
- Verified SHA256 equality between canonical shared favicon files and the corresponding `/static/favicons/...` HTTP responses.
- Recorded deployment backup `/root/nitetime-backups/favicon-20260816-180338` and source package `/srv/nitetime-archive/SOFTWARE/nitetime-favicon-package.zip`.
- Left `/static/favicons/safari-pinned-tab.svg` as a separate Safari SVG mask asset; it was not redirected to PNG/ICO content.
- Added persistent favicon assets and `nitetime-favicon.conf` to the documented shared-asset and backup/recovery model.

### 2026-08-14

- Added the previously undocumented `news.nitetime.net` Usenet/NNTP service to the network operating reference.
- Confirmed InterNetNews (INN) 2.6.4, with public NNTP on TCP `119` via `innd` and a dedicated secure NNTPS reader on TCP `563` via `nnrpd` and `nitetime-nntps.service`.
- Documented the current `readers.conf` policy: anonymous Internet users may read `nitetime.*` but may not post; authenticated TLS users may read/post; trusted localhost applications may read/post.
- Recorded the current secure-user authenticator `ckpasswd -f /var/lib/news/nitetime-users`; `/etc/news/passwd.nntp` had zero active entries during the audit.
- Documented INN configuration paths, tradspool storage paths, and the `nitetime.*:A:never:never:never` retention rule.
- Recorded the ten current Nitetime groups: announce, general, music, radio, ufo, commodore, wisco608, projects, tech, and offtopic.
- Documented NewsPortal under `/var/www/news.nitetime.net`, nginx, PHP 8.1 FPM, localhost NNTP access, protected internal paths, protected article cancellation, and confirmed that browser posting is operational. The base config still shows `$readonly=true`; the effective override/runtime mechanism remains to be re-verified before documenting that implementation detail.
- Added the `news` service account, ports `119`/`563`, NewsPortal HTTPS checks, NNTP/NNTPS health checks, news TLS paths, and news backup targets.

### 2026-08-13

- Added documented workstation Files publishing root at `/home/mac/NITETIME/FTP-ARCHIVE`; server-side Files synchronization internals remain marked for live re-verification rather than being inferred.
- Documented the operational AI-assisted Comics -> Files -> Gopher publishing workflow, including the canonical Ace & Jack source area, derived `/home/mac/NITETIME/GOPHER/comics` tree, public manifest/checksum readiness contract, and the explicit requirement to re-audit final script/timer names before recording them.
- Documented the expanded MUD visual-canon foundation: persistent structured Character appearance, appearance wizard, visible equipment state, stable visual identity, and structured room/object visual metadata.
- Documented the implemented MUD Field Camera flow: `frame`, `snap`, persistent private Photo records, `photos` / `photo <photo-id>`, and JSON render jobs under `/home/evennia/nitetime/server/camera_outbox/pending`.
- Recorded the successful manual MUD-camera rendering proof on the Mac under `/home/mac/NITETIME/MUD-CAMERA-RENDERER`, including confirmed artifact `NT-PHOTO-000004`.
- Recorded successful manual rendering of a real second player Character using that Character's defined MUD appearance.
- Marked automatic MUD photo development, Files/Gopher photo publication, completion receipts, and full persistent Character-reference continuity as IN DEVELOPMENT rather than deployed.
- Added the Signal Mesh architecture as an in-development cross-service design, grounded in the verified MUD -> immutable render job -> real image proof.
- Deployed Nitetime Veronica search in both web and native Gopher forms.
- Added Veronica web backend on `127.0.0.1:9003` and native Gopher service on public TCP `7071`.
- Documented Veronica components under `/opt/nitetime-veronica/`, SQLite index at `/var/lib/nitetime-veronica/veronica.db`, shared `banner.txt`, systemd units, index timer, bounded searches, and `/secrets/` exclusion.
- Confirmed Gophernicus remains `-nx`; dynamic services are isolated instead of enabling Gopher CGI.
- Added dynamic Nitetime live system status at `https://gopher.nitetime.net/status/` and native Gopher TCP `7072`, selector `status`.
- Documented `/opt/nitetime-status/`, `status_core.py`, web/Gopher renderers, root-only aggregate metrics collector, sanitized `/var/lib/nitetime-status/metrics.json`, `nitestatus` service account, and status timer/services.
- Confirmed NodeBB 4.14.8 at `/home/nodebb/nodebb` using PostgreSQL database `nodebb` on `127.0.0.1:5432`.
- Recorded current BBS metrics issue: HTTP availability is visible, but public NodeBB API did not expose user/topic/post/online counts; PostgreSQL-backed aggregate collection is the next verified integration path.
- Updated Gopher root menu architecture and documented client whitespace-collapse limitations for ASCII art and headings.
- Recorded the 2026-08-13 Gopherspace snapshot: 624 files, 1,220,560 actual bytes (1.16 MB), no empty files.
- Confirmed the Gopher browser gateway's external HTTP/HTTPS `h` link handling is repaired and deployed.
- Replaced the global control-bar path TODO with verified live paths under `/var/www/nitetime-global/` and nginx snippets under `/etc/nginx/snippets/`.
- Added native Veronica/status and web backend ports `7071`, `7072`, `9003`, and `9004` to the system port map and health checks.

### 2026-08-12

- Confirmed `gopher.nitetime.net` nginx reverse-proxies to the localhost Python gateway at `127.0.0.1:9002`.
- Confirmed Gopher web gateway runtime: `/usr/bin/python3.10 /opt/nitetime-gopher-web/gateway.py`, working directory `/opt/nitetime-gopher-web`, service account `gopherweb`, systemd unit `nitetime-gopher-web.service`.
- Diagnosed the browser gateway `[WEB]` defect: valid Gopher `h` / `URL:https://...` selectors are incorrectly passed through the normal local selector builder, leaving the `URL:` prefix intact and appending `?type=h`.
- Added the required gateway repair pattern and validation procedure while explicitly leaving deployment status unconfirmed until tested live.
- Documented the `gophersync` Syncthing service, localhost GUI/API at `127.0.0.1:37125`, folder ID `nitetime-gopher`, label `NITETIME GOPHER`, `/var/gopher/.stfolder`, and `syncthing@gophersync.service`.
- Added dedicated documentation for the global Nitetime browser control bar, confirmed `/_nitetime/controlbar.js` integration on the Gopher HTTPS gateway, its separation from native/service-specific navigation, safe change/testing procedure, backup requirements, and unresolved path/menu details that still require live verification.

- Documented the Nitetime Gopher service at `gopher.nitetime.net:70`.
- Documented Gophernicus 3.1.1 and the live Gopher document root `/var/gopher`.
- Documented the workstation synchronized Gopher publishing tree at `/home/mac/NITETIME/GOPHER`.
- Documented the local `conderman.group` Wayback recovery source at `/home/conderman-recovered/site`.
- Documented the local Codex Gopher curator workflow under `/home/mac/gopher-importer`.
- Recorded that Codex edits the synchronized workstation copy and does not directly edit the live server Gopher tree.
- Added native and browser Gopher health checks and port 70 to the port map.
- Added Gopher files and local publishing/importer state to backup targets.
- Added the planned Nitetime-only Veronica terminal design.
- Recorded Veronica safety boundaries: local index only, no remote crawling, no shell execution of queries, read-only query endpoint, bounded queries/results, and clickable native Gopher results.

### 2026-08-10

- Document created.
- MediaCMS documented as the primary Nitetime website.
- NodeBB documented at `bbs.nitetime.net`.
- Evennia MUD documented at `mud.nitetime.net`.
- Ergo IRC documented at `irc.nitetime.net:6697`.
- The Lounge documented at `chat.nitetime.net`.
- Owncast documented at `live.nitetime.net`.
- MediaCMS hard-coded sidebar customization procedure documented.
- Node.js isolation notes documented.
- Let's Encrypt certificate layout documented.

---

## 20. NITETIME.NET // SYSTEM STATUS

```text
MAIN WEB ............... ONLINE
LIVE VIDEO ............. ONLINE
BBS .................... ONLINE
MUD .................... ONLINE
IRC .................... ONLINE
WEB CHAT ............... ONLINE
NEWS WEB ................ ONLINE
NNTP :119 ............... ONLINE
NNTPS :563 .............. ONLINE
NEWS ANON READ .......... ENABLED
NEWS AUTH POST .......... ENABLED ON TLS
NEWS WEB POSTING ........ EFFECTIVE STATE NOT YET VERIFIED

GOPHER .................. ONLINE
GOPHER WEB LINKS ........ FIXED / DEPLOYED
GOPHER SYNC ............. ACTIVE
ARCHIVE RECOVERY ........ ACTIVE

VERONICA WEB ............ ONLINE
VERONICA NATIVE ......... ONLINE
VERONICA INDEX .......... ACTIVE
VERONICA /SECRETS/ ...... EXCLUDED FROM SEARCH

LIVE STATUS WEB ......... ONLINE
LIVE STATUS GOPHER ...... ONLINE
STATUS METRICS .......... ACTIVE
BBS AGGREGATE COUNTS .... POSTGRES INTEGRATION PENDING VERIFICATION

GLOBAL CONTROL BAR ...... ACTIVE
GLOBAL ASSET PATHS ...... VERIFIED
GLOBAL FAVICON .......... CUSTOM / ACTIVE
FAVICON BUILD SAFETY .... NGINX-PERSISTENT / MEDIACMS-INDEPENDENT

FILES PUBLISHING ROOT ... DOCUMENTED
AI->GOPHER COMICS ........ OPERATIONAL

MUD VISUAL CANON ........ IMPLEMENTED / TESTED
MUD APPEARANCE WIZARD ... IMPLEMENTED
MUD FIELD CAMERA ........ SNAPSHOT / QUEUE VERIFIED
MUD PHOTO RENDERING ..... MANUAL PROOF VERIFIED
MUD CHARACTER PHOTO ..... MULTIPLAYER PROOF VERIFIED
MUD PHOTO AUTO-LAB ...... IN DEVELOPMENT
MUD PHOTO FILES/GOPHER .. IN DEVELOPMENT
CHARACTER REF CONTINUITY  IN TESTING

GOPHERNICUS CGI ......... DISABLED (-nx)

LAKE KOSHKONONG NODE
WISCO 608

SIGNAL ACTIVE
```
