Files
JL Kruger 5422131782 Initial commit — Singular Particular Space v1
Homepage (site/index.html): integration-v14 promoted, Writings section
integrated with 33 pieces clustered by type (stories/essays/miscellany),
Writings welcome lightbox, content frame at 98% opacity.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 12:09:22 +02:00

11 KiB

Meshagora — Deployment & Troubleshooting


Version History

v0.2 — IP Detection & Startup Transparency

  • Replaced UDP routing trick with ifconfig parsing for hotspot IP detection. The UDP trick failed on the Samsung A25 (and likely other Android builds) because the hotspot interface routing entry may not exist at startup. ifconfig reads interface addresses directly via socket ioctls — no netlink, no root, no routing assumptions.
  • Startup banner now lists all detected non-loopback IPs with interface names, so if the primary guess is wrong the alternatives are immediately visible.
  • Added install_termux.sh — one-shot setup script for Termux.
  • Added net-tools as an explicit dependency (ifconfig provider).

v0.1 — Initial prototype

  • Single-file Flask app, in-memory SQLite, runs on Android/Termux hotspot.

Dependencies

Termux (Android) — required packages

Package Source Purpose
python pkg Runtime
net-tools pkg ifconfig — hotspot IP detection
libjpeg-turbo pkg JPEG support for Pillow (required by qrcode[pil])
libpng pkg PNG support for Pillow (required by qrcode[pil])
flask pip Web framework
qrcode[pil] pip QR code generation at /qr

Desktop (testing only)

Package Source Purpose
flask pip Web framework
qrcode[pil] pip QR code generation

ifconfig is standard on desktop Linux/macOS — no extra install needed.


Quick Start (Termux)

First time only — install dependencies:

bash install_termux.sh

Or manually:

pkg install python net-tools libjpeg-turbo libpng
pip install flask "qrcode[pil]"

Every session:

  1. Enable Android mobile hotspot.
  2. Open Termux and run:
    python3 meshagora.py
    
  3. Read the startup banner — note all three keys and the Join URL.
  4. Open http://[IP]:5000/qr on the server device and display it for participants to scan.
  5. Once everyone has joined, go to /admin → HIDE QR.

Starting the Server

  1. Enable the Android mobile hotspot before running the script. IP detection reads active interfaces at startup — if the hotspot is off, the banner URL will be wrong.

  2. Run:

    python3 meshagora.py
    
  3. The startup banner prints:

    ==================================================
    MESHAGORA v2.3 — SOCIAL SANDBOX
    Admin Post Key   : [4 emoji]
    Trusted Post Key : [2 emoji]
    Default Post Key : [2 emoji]
    --------------------------------------------------
    Join URL  : http://192.168.43.1:5000/join  (wlan0)
    Also try  : http://10.0.2.5:5000/join      (rmnet0)
    QR code   : http://192.168.43.1:5000/qr
    If no URL works, run:  ifconfig | grep inet
    ==================================================
    

    Write down or photograph all three keys. They cannot be recovered without restarting the server (which destroys the session).

    Reading the banner:

    • "Join URL" is the best-guess hotspot address (192.168.x.x preferred).
    • "Also try" lines show other detected interfaces. The rmnet / 10.x.x.x entries are mobile data — participants on the hotspot WiFi cannot reach those.
    • Samsung A25 hotspot is typically 192.168.43.1 on wlan0.
  4. Navigate to http://[IP]:5000/qr on the server device and display the QR code for participants to scan.

  5. Once all participants have joined, hide the QR code from the Admin Panel (/admin → HIDE QR).


Connecting Participants

Participants need to:

  1. Join the hotspot WiFi (name set by the server device's hotspot settings).
  2. Open a browser and scan the QR code, or type the Join URL from the banner.
  3. Go to /join — choose a username, Profile Key (2 emoji), and Friend Key (2 emoji).

No app install required. Works on any browser from Android 7.0+, iOS Safari, desktop Chrome/Firefox.


Admin Panel

Navigate to /admin from any browser connected to the hotspot. Enter the 4-emoji Admin Post Key when prompted. Authentication persists for that browser session.

Actions available:

  • Restrict / Unrestrict / Promote / Demote individual users
  • View the current Default Post Key (large, readable — copy to board or announce verbally)
  • Rotate Default Key manually
  • Trigger Flood Attack (creates 5 bot accounts with posts)
  • Show / Hide the join QR code
  • View raw database tables (users, posts, votes, reports, keys)
  • WHAT THE PLATFORM SEES — surveillance dashboard (scroll to bottom of admin panel):
    • Deanonymization table: maps every session label (Anon #N) to real username, tier, post count, and net score
    • Social graph: all handshake pairs with CONFIRMED / PENDING status
    • Behavioral correlations: who voted for whom and who reported whom, cross-referenced with confirmed friendships — project mid-session for maximum pedagogical impact

Stopping the Server

Ctrl+C in the Termux terminal. The in-memory database is destroyed immediately. There is no persistent storage — every session starts clean.


Troubleshooting

Server prints 127.0.0.1 instead of the hotspot IP

Important: 127.0.0.1 is the loopback address — it only works in the browser on the server device itself. Participants on other devices will get "connection refused". Flask is still listening on all interfaces (0.0.0.0), so the server is reachable — you just need the correct IP.

Step 1: Enable the mobile hotspot before running python3 meshagora.py, then restart. The hotspot interface only appears after the hotspot is on.

Step 2: If still wrong, check all interfaces manually:

ifconfig | grep inet

Look for an address like 192.168.43.1 under wlan0 — that's the hotspot gateway. Ignore 127.0.0.1 (loopback) and 10.x.x.x under rmnet (mobile data).

Note: ip addr fails in Termux with "cannot bind netlink socket: permission denied" — always use ifconfig instead.

Step 3: Navigate to http://[correct-ip]:5000/join directly and distribute that URL to participants.

Samsung A-series: The A25 hotspot is typically 192.168.43.1 on wlan0. If the banner's "Join URL" shows a different address, check the "Also try" lines for the 192.168.43.1 entry.


ModuleNotFoundError: No module named 'qrcode'

pip install "qrcode[pil]"

If it installs but the error persists:

python3 -m pip install "qrcode[pil]"

The server runs without qrcode — /qr returns a 404. Participants can type the join URL directly.


ModuleNotFoundError: No module named 'flask'

pip install flask

ifconfig command not found

pkg install net-tools

This is required for hotspot IP detection in Termux. Without it, the banner will fall back to 127.0.0.1.


Port 5000 already in use

Common on macOS (AirPlay Receiver uses 5000).

Option A: Kill the other process:

lsof -i :5000
kill [PID]

Option B: Change the port at the bottom of meshagora.py:

app.run(host='0.0.0.0', port=5001, debug=False, threaded=False)

Update the join URL accordingly.


Participants can't reach the server

  1. Confirm participants are connected to the hotspot WiFi, not their mobile data or a different network.
  2. Confirm the IP in the banner matches ifconfig | grep inet output for the wlan0 interface.
  3. Confirm port 5000 is not blocked by a firewall. On Termux this is rarely an issue on a local hotspot.
  4. Try navigating to the URL from the server device's own browser first to confirm the server is responding.

Android kills the server mid-session (Termux background kill)

Android aggressively kills background processes to save battery.

Prevention:

  • In Android Settings → Apps → Termux → Battery → set to "Unrestricted" (wording varies by device).
  • Keep Termux in the foreground with the screen on, or acquire a wakelock:
    termux-wake-lock
    
    (Requires the Termux:API app from F-Droid.)
  • Keep the server device plugged in to power.

If the server is killed, all session data is lost. Restart with python3 meshagora.py — all keys rotate, all users must rejoin.


Default Post Key stopped working for everyone

A user was restricted (by admin action or by 51% community reports). The Default Post Key rotates silently on every restriction. Check the Admin Panel for the new key and distribute it.


Emoji picker doesn't appear / looks broken

The emoji picker is rendered as inline HTML buttons with basic CSS. No JavaScript framework required.

  • If buttons appear but emoji don't render: the device font doesn't support those codepoints. This is rare on Android 7.0+ but possible on stripped-down browsers. Participants can type emoji directly into the visible input field.
  • If the grid looks misaligned: the scroll container (max-height: 160px; overflow-y: auto) is intentional. Scroll within the picker to see all emoji.

Post fails with "Post key incorrect." for a RESTRICTED user

RESTRICTED users require an admin co-sign. The admin must communicate the Admin Post Key directly to the restricted user for them to post. This is by design — it represents supervised posting access.


Handshake says "One or both keys are incorrect."

  • Both participants must submit from their own accounts (you cannot complete both sides from one account).
  • Emoji must match exactly — the picker submits codepoints, not descriptions.
  • Try clearing both fields and reselecting. The CLEAR button resets the hidden input.
  • Verify both participants have submitted independently.

Testing Checklist (Pre-Session)

  • Hotspot enabled before starting server — correct IP appears in banner
  • /qr loads a scannable QR code from the server device
  • Join as User 1 from a phone — "Anon #1" assigned, Default Post Key shown on join confirmation
  • Join as User 2 from a second device or incognito tab — "Anon #2" assigned
  • Post from User 1 with correct Default Post Key — appears in feed
  • Post from User 1 with wrong key — "Post key incorrect." error
  • Vote from User 2 — score updates
  • Report from User 2 — spoiler overlay appears, User 1 sees notification banner
  • Admin panel accessible at /admin with 4-emoji Admin Post Key
  • Admin restricts User 1 — Default Post Key rotates (new key visible in admin panel)
  • User 1 post fails with old key, succeeds with new key (or admin co-sign)
  • Handshake between User 1 and User 2 — confirmed, username appears on posts for the friend
  • Friends-only toggle shows only friend posts
  • Profile notes edit blocked without Profile Key, succeeds with correct key
  • Hide QR via admin → /qr returns 404
  • Flood Attack → 5 bot posts appear in feed
  • Scroll to "WHAT THE PLATFORM SEES" in admin panel — all three panels render (deanonymization, social graph, behavioral correlations)
  • Confirm panels are empty (no crash) on a fresh session with no posts/votes/reports