Commit graph

5 commits

Author SHA1 Message Date
337011fa03
refactor(pods): drop redundant tuneApt apt-sandbox hack (#31)
The rootless-podman default capability set (already on main) lets apt drop
to the _apt user on its own, so disabling the apt download sandbox via
tuneApt is dead code. Removing it; apt now works the proper way.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 08:23:54 -07:00
2d6fba5f16 fix(pods): self-heal pre-existing pods to pick up the public_html bind
The box auto-deploys (self-update timer pulls origin/main, rebuilds, restarts
agentbbs), but `systemctl restart agentbbs` only restarts the daemon — it never
touches the long-lived per-user pod containers. ensure() also short-circuits on
any container that already exists, so pods created before the homepage bind
landed would never gain the /home/dev/public_html mount without a manual
`podman rm`. That defeats the "everything happens automatically on push" goal.

Make ensure() self-healing: when a pod exists but lacks the public_html mount,
recreate it so the bind is applied. The named home volume survives `rm`, so the
member's files are kept. Only heal when the pod is idle (attached count 0) to
avoid pulling a running pod out from under an active session — an unbound pod
heals on its next idle attach. New hasMount() inspects the container's mounts.

Net effect: push to main -> self-update redeploys within the timer interval ->
the next `ssh pod@` recreates the pod with the bind. No manual step.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 13:50:06 +00:00
06bc5631d8 fix(pods): bind-mount host public_html into the pod so ~/public_html is served
A member's pod home (/home/dev) is a named container volume, but Caddy serves
<name>.<host> from the host path <data>/users/<name>/public_html. The two were
disconnected, so editing ~/public_html/index.html in the pod never changed the
served page — contradicting the on-screen "edit ~/public_html to make it yours"
instruction.

Bind-mount <data>/users/<user>/public_html at /home/dev/public_html when pods
start. The host tree is created if absent so the mount source exists, and under
the docker fallback (uid 1000) the one-shot init container now also chowns the
bind path; rootless podman maps container root to the host service user that
already owns the tree, so no chown is needed there.

Detect now takes the host users dir; pass "" to disable the bind.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 13:42:08 +00:00
4be87440d5 tor: premium tor-url / tor-irc / tor routes over Tor
Add three premium-gated SSH routes:
  ssh tor-url@host <url>        one-shot HTTP(S) GET over Tor (host-side,
                               curl via SOCKS, 30s/2MB caps, http/https only)
  ssh -t tor-irc@host <server>  interactive IRC over Tor in the member's pod
  ssh -t tor@host <command...>  run any command over Tor (torsocks) in the pod

tor-url runs host-side and constrained; tor/tor-irc run inside the member's
isolated pod (new pods.Exec) so arbitrary/interactive commands are sandboxed,
never on the host. internal/tor wraps curl/torsocks/irssi. All gated by
ensurePremium; names reserved. setup.sh installs + enables tor (SOCKS
127.0.0.1:9050) and torsocks.

Note: tor-url is host-side and self-contained. tor/tor-irc still need the pod
image to carry torsocks+irssi and reach the Tor SOCKS — follow-up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 10:54:21 +00:00
f3b085a08f AgentBBS: M0 core hub, M1 arcade, pods with CoinPay membership
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>
2026-06-11 11:08:17 +00:00