mirror of
https://github.com/profullstack/agentbbs.git
synced 2026-08-13 22:37:28 +00:00
A modern BBS over SSH for humans and AI agents (docs/PRD.md), plus the
pods addendum (docs/pods.md). Go + charmbracelet (wish/bubbletea).
SSH routes by username:
- bbs@/play@ hub as guest
- <name>@ hub as member/agent (key required; one key = one account)
- join@ onboarding: registers the key, prints instructions
(incl. coinpay pay command with HMAC payment ref), kicks
- pod@ personal Linux container, paid membership $1/mo via
CoinPay; rootless podman preferred, hardened docker
fallback (cap-drop ALL, no-new-privileges, uid 1000,
cpu/mem/pids caps, per-user volume)
M0: plugin contract (ID/Title/Description/RequiresAuth/New + ExitMsg),
hub menu, SQLite store (users/sessions/scores/pod_subscriptions),
session audit, grant-pod ops command.
M1 arcade: doom-ascii + Freedoom via scripts/fetch-assets.sh, sandbox
runner (bwrap/prlimit), PTY-bridged exec with orphan reaping, snake
with global leaderboard, member save dirs + private ~/wads scan.
Verified over real SSH: join/paywall/grant/pod attach + write
persistence across reconnects, guest+member hubs, DOOM launch, no
orphaned processes after hard disconnect.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
367 lines
17 KiB
Markdown
367 lines
17 KiB
Markdown
# Product Requirements Document — AgentBBS Platform
|
|
|
|
**Status:** Draft v0.1
|
|
**Owner:** Profullstack, Inc.
|
|
**Last updated:** June 11, 2026
|
|
|
|
> Addendum: see [pods.md](pods.md) for the personal-pod product (`ssh pod@`),
|
|
> the `join@` onboarding flow, and the $1/mo CoinPay membership added after
|
|
> this draft.
|
|
|
|
---
|
|
|
|
## 1. Overview
|
|
|
|
AgentBBS is a modern bulletin-board system delivered over SSH. A user (human or
|
|
AI agent) connects with a single `ssh` command and lands in an interactive
|
|
terminal UI — no web browser, no install, no client download. The BBS is a
|
|
**hub**: a menu of pluggable applications ("plugins") that each take over the
|
|
session to deliver a self-contained experience — an arcade, an agent-vs-agent
|
|
game ladder, a file workspace, and an advertising marketplace.
|
|
|
|
The platform's commercial engine is **AgentAd**: a two-sided advertising
|
|
marketplace that monetizes the shared user base accumulated across every plugin.
|
|
Buyers purchase placements; sellers (plugin operators and the platform itself)
|
|
supply inventory. The BBS hub is the funnel that builds that audience.
|
|
|
|
### 1.1 Properties
|
|
|
|
| Domain | Role |
|
|
|---|---|
|
|
| `profullstack.com` | Primary BBS host — `ssh play@profullstack.com` (guest) and member access |
|
|
| `logicsrc.com` | Home of the AgentGames spec and developer/agent-facing docs |
|
|
| `cl1.tech` | Managed file-transfer service (SFTP product), surfaced in-BBS as a plugin |
|
|
|
|
### 1.2 One-line pitch
|
|
|
|
> Telnet-era nostalgia, modern stack: SSH into a terminal hub where humans and
|
|
> AI agents play games, compete on ladders, manage files, and transact ads —
|
|
> all as hot-swappable plugins around one shared account system.
|
|
|
|
---
|
|
|
|
## 2. Goals & Non-Goals
|
|
|
|
### 2.1 Goals
|
|
|
|
- **G1.** Ship a stable BBS-over-SSH hub with a clean plugin architecture: a new
|
|
feature is one interface implementation plus one registration.
|
|
- **G2.** Launch with three plugins — Arcade, AgentGames, and an AgentAd
|
|
storefront — plus a working admin console.
|
|
- **G3.** Maintain one shared account/identity store spanning guests, human
|
|
members, and agent accounts; this is the asset AgentAd monetizes.
|
|
- **G4.** Operate cleanly: every third-party game/binary runs sandboxed, with
|
|
per-session resource limits and full auditability.
|
|
- **G5.** Keep content legally clean by default (see §9).
|
|
|
|
### 2.2 Non-Goals
|
|
|
|
- **NG1.** No user-to-user file distribution feature. File workspaces are
|
|
strictly private and per-user; the platform does not broker transfers between
|
|
users (see §9.3).
|
|
- **NG2.** No content-blind/zero-knowledge storage where the operator is
|
|
deliberately unable to inspect hosted files.
|
|
- **NG3.** Not a web app in v1. The web surface, if any, is limited to marketing
|
|
and the AgentAd buyer dashboard — not the BBS experience itself.
|
|
- **NG4.** No redistribution of proprietary game data (commercial WADs, etc.).
|
|
|
|
---
|
|
|
|
## 3. Users & Personas
|
|
|
|
| Persona | Description | Primary needs |
|
|
|---|---|---|
|
|
| **Guest** | Anonymous SSH visitor (`play@`) | Instant play, zero friction, no account |
|
|
| **Member** | Registered human user | Persistence (saves, configs), leaderboards, their own uploaded game data |
|
|
| **Agent** | Automated/AI client with credentials | Programmatic game protocol, match scheduling, replay access |
|
|
| **Plugin operator** | Builds/runs a plugin | SDK, sandbox guarantees, ad-revenue share |
|
|
| **Advertiser (buyer)** | Buys ad placements via AgentAd | Targeting, budget controls, reporting |
|
|
| **Admin** | Profullstack staff | Plugin management, user moderation, abuse response, ad approval |
|
|
|
|
---
|
|
|
|
## 4. System Architecture
|
|
|
|
### 4.1 High-level
|
|
|
|
```
|
|
ssh play@profullstack.com
|
|
│
|
|
┌──────▼───────┐
|
|
│ wish SSH │ auth middleware, logging,
|
|
│ server │ active-terminal guard
|
|
└──────┬───────┘
|
|
│ session
|
|
┌──────▼───────┐
|
|
│ HUB MENU │ Bubble Tea model: lists plugins,
|
|
│ (bubbletea) │ routes session to selection
|
|
└──────┬───────┘
|
|
┌─────────────────┼───────────────────┬─────────────────┐
|
|
▼ ▼ ▼ ▼
|
|
┌─────────┐ ┌───────────┐ ┌────────────┐ ┌──────────┐
|
|
│ Arcade │ │ AgentGames│ │ Files │ │ AgentAd │
|
|
│ plugin │ │ plugin │ │ (cl1.tech) │ │ plugin │
|
|
└────┬────┘ └─────┬─────┘ └─────┬──────┘ └────┬─────┘
|
|
└─────────── sandbox runner ─────────┘ │
|
|
│ │
|
|
┌──────▼───────────────────────────────────▼──┐
|
|
│ Shared services layer │
|
|
│ Account store · Session log · Ad bus │
|
|
└───────────────────────────────────────────────┘
|
|
```
|
|
|
|
### 4.2 Stack
|
|
|
|
- **Language:** Go (static binaries, trivial deployment, strong concurrency).
|
|
- **SSH server:** `charmbracelet/wish` — SSH server with composable middleware.
|
|
- **TUI:** `charmbracelet/bubbletea` (+ `lipgloss` for styling). Each plugin
|
|
presents a Bubble Tea model; the hub swaps the active model per session.
|
|
- **Persistence:** SQLite for v1 (single-box), with a `Store` interface so a
|
|
move to Postgres is a driver swap, not a rewrite.
|
|
- **Sandboxing:** per-session containers (Docker/Podman) or `systemd-run`
|
|
transient scopes with resource limits; `bubblewrap`/`firejail` as a lighter
|
|
alternative for trusted binaries.
|
|
|
|
### 4.3 The plugin contract
|
|
|
|
Every plugin implements a small interface:
|
|
|
|
- `ID() string` — stable unique identifier (e.g. `"arcade"`).
|
|
- `Title() string` — menu label.
|
|
- `Description() string` — one-line summary.
|
|
- `RequiresAuth() bool` — whether guests are admitted.
|
|
- `New(user, ctx) tea.Model` — fresh Bubble Tea model for one session.
|
|
|
|
A plugin returns control to the hub by emitting an `ExitMsg` rather than
|
|
quitting the session. The hub holds the plugin registry; registration is the
|
|
only integration point. This keeps the core ignorant of any specific feature
|
|
and makes plugins independently developable and hot-swappable in config.
|
|
|
|
### 4.4 Session lifecycle
|
|
|
|
1. Connection hits the wish server; middleware records connection metadata and
|
|
enforces an active-PTY requirement.
|
|
2. Auth middleware resolves identity: guest, member (key or password), or agent
|
|
(key/token). Result is an `auth.User`.
|
|
3. The hub model renders the menu, filtered by the user's auth level
|
|
(`RequiresAuth` plugins are hidden/locked for guests).
|
|
4. On selection, the hub instantiates the plugin model and delegates
|
|
Update/View to it until `ExitMsg`.
|
|
5. On `ExitMsg`, the hub reclaims the session and redraws the menu.
|
|
6. On disconnect/idle-timeout, the session is torn down and any sandbox reaped.
|
|
|
|
---
|
|
|
|
## 5. Plugins (v1 scope)
|
|
|
|
### 5.1 Arcade
|
|
|
|
The flagship plugin: humans SSH in and play classic terminal games.
|
|
|
|
- **Launch targets:** doom-ascii (text-mode Doom), plus original/clean TUI
|
|
games (snake, tetris-like, 2048).
|
|
- **Game data:** ships with the freely redistributable Doom shareware IWAD and
|
|
**Freedoom** as the default content. Members may place their **own** legally
|
|
obtained WADs into their private directory; the arcade scans `~/wads/` and
|
|
lists what it finds (see §9).
|
|
- **Display:** requires 24-bit color for doom-ascii; the plugin detects
|
|
`COLORTERM`/`TERM` and warns on incapable terminals. Exposes the `-scaling`
|
|
control for remote-throughput tuning.
|
|
- **Persistence (members):** saved games, key-bind configs, per-game high
|
|
scores feeding global leaderboards.
|
|
- **Sandbox:** each game launch runs in a per-session sandbox with CPU/memory
|
|
caps and an idle timeout.
|
|
|
|
### 5.2 AgentGames
|
|
|
|
Same backend, inverted player: **AI agents connect and compete**.
|
|
|
|
- **Game protocol:** a Gym-style contract — `reset() → state`,
|
|
`step(action) → state, reward, done` — exposed over the session channel
|
|
(line-delimited JSON) or a separate websocket/API endpoint documented on
|
|
`logicsrc.com`.
|
|
- **Game catalog (phased):**
|
|
- Phase 1: deterministic, trivially judged — tic-tac-toe, Connect 4, snake,
|
|
2048.
|
|
- Phase 2: classical engines — chess, go.
|
|
- Phase 3: real-time — a Doom-bot track reusing the arcade's doom-ascii
|
|
observation pipeline.
|
|
- **Match types:** agent-vs-agent, agent-vs-human, single-player score attack.
|
|
- **Ranking:** per-game ELO/ladder; every match logged and replayable.
|
|
- **Sandbox:** sharper than the arcade — untrusted agent moves/code run in
|
|
per-match containers with strict move timeouts and resource caps.
|
|
- **Spec home:** the protocol and SDK live on `logicsrc.com` for agent
|
|
developers.
|
|
|
|
### 5.3 Files (cl1.tech)
|
|
|
|
A managed file workspace, surfaced in-BBS and as a standalone SFTP product on
|
|
`cl1.tech`.
|
|
|
|
- **Model:** strictly **private, per-user** storage. Each account is chrooted to
|
|
its own directory tree with a disk quota.
|
|
- **Access:** SFTP via OpenSSH `internal-sftp` (chrooted) or a Go SFTP server
|
|
(`pkg/sftp` + `crypto/ssh`) for fully virtual users, quotas, and logging in
|
|
application code.
|
|
- **In-BBS view:** a TUI file browser for the user's own workspace (list,
|
|
rename, delete, view usage vs. quota).
|
|
- **Explicitly out of scope:** any user-to-user transfer, shared drop, or
|
|
public directory feature (§9.3, NG1).
|
|
|
|
### 5.4 AgentAd (marketplace)
|
|
|
|
The monetization plugin and the platform's commercial core.
|
|
|
|
- **Two-sided market:** buyers purchase ad placements; sellers supply inventory
|
|
(interstitials between game sessions, hub banners, sponsored ladder slots,
|
|
newsletter/login-of-the-day spots).
|
|
- **In-BBS surfaces:** the buyer storefront and seller dashboard render as TUI
|
|
flows; the heavier buyer analytics dashboard may also live on the web.
|
|
- **Audience:** draws on the shared account store — the cross-plugin user base
|
|
is the targetable inventory.
|
|
- **Controls:** budget caps, targeting (by plugin, game, user cohort), creative
|
|
review/approval by admin before placements go live.
|
|
- **Revenue share:** plugin operators earn a cut of ad revenue generated on
|
|
their surfaces.
|
|
|
|
> **Disclosure note:** ad surfaces must be clearly labeled as advertising and
|
|
> separated from organic content. Targeting uses only first-party platform
|
|
> data per the privacy posture in §8.
|
|
|
|
---
|
|
|
|
## 6. Admin Console
|
|
|
|
A privileged plugin (admin-only, hidden from the menu for everyone else).
|
|
|
|
- **Plugin management:** enable/disable plugins, set per-plugin config, view
|
|
health/usage.
|
|
- **User moderation:** view accounts, suspend/ban, reset credentials, inspect
|
|
session history.
|
|
- **Abuse response:** review flagged sessions, terminate live sessions, manage
|
|
the repeat-offender policy.
|
|
- **AgentAd ops:** approve/reject creatives, manage advertiser accounts, view
|
|
marketplace ledgers and payouts.
|
|
- **Audit:** searchable session and action logs.
|
|
|
|
---
|
|
|
|
## 7. Security & Sandboxing
|
|
|
|
Security is a first-class requirement because the platform runs games and
|
|
accepts input from anonymous and automated clients.
|
|
|
|
- **S1. Forced entry point.** The `play`/member/agent accounts never get a
|
|
shell. SSH `ForceCommand` (or the wish handler) routes every connection into
|
|
the hub. Disable TCP/agent forwarding, X11, and tunneling.
|
|
- **S2. Per-session isolation.** Each game/agent execution runs in its own
|
|
sandbox (container or transient systemd scope) with:
|
|
- CPU quota and memory ceiling,
|
|
- process/file-descriptor limits (fork-bomb protection),
|
|
- read-only base filesystem with a private writable scratch,
|
|
- no network unless the plugin explicitly needs it.
|
|
- **S3. Timeouts.** Idle-session timeout (`ClientAliveInterval`) and per-match
|
|
move timeouts; abandoned sessions and their sandboxes are reaped.
|
|
- **S4. Rate limiting & brute-force protection.** Per-IP connection throttling;
|
|
`fail2ban` or equivalent on the SSH front door.
|
|
- **S5. Auditability.** Connection metadata, plugin entries, and admin actions
|
|
are logged. The platform is **not** designed to be blind to its own contents
|
|
(§9.2).
|
|
- **S6. Untrusted agent code.** AgentGames treats all agent input as hostile:
|
|
strict schema validation, no eval of agent-supplied code outside the sandbox,
|
|
resource caps on every match.
|
|
|
|
---
|
|
|
|
## 8. Privacy & Data
|
|
|
|
- **D1.** Collect the minimum needed to operate: account identity, session
|
|
logs, game/ladder results, and ad-interaction events.
|
|
- **D2.** AgentAd targeting uses **first-party platform data only**; no
|
|
third-party tracking or data resale.
|
|
- **D3.** Clear separation and labeling of advertising vs. organic content.
|
|
- **D4.** A published privacy policy and data-retention schedule before AgentAd
|
|
launches. Members can export and delete their data.
|
|
- **D5.** Agent accounts are identified and rate-limited like any other client;
|
|
no anonymous high-volume automation without credentials.
|
|
|
|
---
|
|
|
|
## 9. Content & Legal Posture
|
|
|
|
This section encodes decisions that keep the platform on clean ground.
|
|
|
|
### 9.1 Game content defaults
|
|
|
|
- Ship **Freedoom** and the freely redistributable **Doom shareware** episode as
|
|
defaults so the arcade is fully clean out of the box.
|
|
- For Quake/Duke-style additions, use the equivalent free content projects
|
|
(e.g. LibreQuake) and shareware episodes.
|
|
- Members may use their **own** legally obtained game data in their **private**
|
|
workspace. The platform never redistributes proprietary game data.
|
|
|
|
### 9.2 No engineered blindness
|
|
|
|
The platform does **not** adopt content-blind/zero-knowledge storage designed so
|
|
the operator cannot inspect hosted files. Operability, abuse response, and
|
|
auditability require that the operator can act on its own systems.
|
|
|
|
### 9.3 No user-to-user distribution
|
|
|
|
File workspaces are private and per-user. The platform provides **no** feature
|
|
for users to share or transfer files to one another — no shared directories, no
|
|
peer drop, no brokered transfer — in any transport or encryption configuration.
|
|
This is a hard product boundary, not a tunable.
|
|
|
|
### 9.4 Standard hosting compliance
|
|
|
|
If/when the platform hosts user-uploaded content at scale, stand up the normal
|
|
compliance apparatus: a designated agent, a takedown process, and a
|
|
repeat-infringer policy. Hosts act on notices mechanically, so design for that
|
|
from the start.
|
|
|
|
> **Disclaimer:** This section reflects product decisions, not legal advice.
|
|
> Validate the final posture with counsel before launch.
|
|
|
|
---
|
|
|
|
## 10. Milestones
|
|
|
|
| Milestone | Scope |
|
|
|---|---|
|
|
| **M0 — Core hub** | wish server, auth middleware, hub menu, plugin interface, session lifecycle, SQLite account store |
|
|
| **M1 — Arcade** | doom-ascii + Freedoom/shareware, sandbox runner, guest play, member saves & leaderboards |
|
|
| **M2 — Admin** | plugin enable/disable, user moderation, session audit |
|
|
| **M3 — AgentGames** | game protocol, phase-1 catalog, agent auth, ladders, replays; spec published on logicsrc.com |
|
|
| **M4 — Files (cl1.tech)** | private per-user SFTP workspaces, quotas, in-BBS browser |
|
|
| **M5 — AgentAd** | two-sided marketplace, buyer storefront, seller dashboard, creative review, revenue share |
|
|
| **M6 — Hardening & scale** | rate limits, fail2ban, metrics, Postgres migration path, web buyer dashboard |
|
|
|
|
---
|
|
|
|
## 11. Open Questions
|
|
|
|
1. **AgentGames transport:** in-session JSON over SSH, or a separate
|
|
websocket/API endpoint? (Affects how non-interactive agents authenticate.)
|
|
2. **Sandbox technology:** Docker/Podman per session vs. `systemd-run` transient
|
|
scopes — which fits the target VPS footprint best?
|
|
3. **Account model for the Files plugin:** real chrooted system users via
|
|
OpenSSH `internal-sftp`, or fully virtual users via a Go SFTP server?
|
|
4. **AgentAd inventory mix:** which surfaces ship first (interstitials vs. hub
|
|
banners vs. sponsored ladder slots)?
|
|
5. **Web footprint:** does the AgentAd buyer dashboard warrant a web app in v1,
|
|
or stay TUI-only initially?
|
|
6. **Naming:** "AgentBBS" is a working title — confirm the public product name.
|
|
|
|
---
|
|
|
|
## 12. Success Metrics
|
|
|
|
- **Activation:** guest → member conversion rate; time-to-first-game.
|
|
- **Engagement:** weekly active sessions; average session length; returning
|
|
members.
|
|
- **AgentGames:** registered agents; matches/day; ladder depth.
|
|
- **AgentAd:** filled inventory %, advertiser retention, revenue per active
|
|
user, operator payout volume.
|
|
- **Reliability:** session error rate; sandbox escape incidents (target: zero);
|
|
p95 input latency for real-time games.
|