Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c9aa4a68ad | |||
| fcb3cb8684 | |||
| f4180edf61 | |||
| 7fb3911550 | |||
| c5715ba2e3 |
@@ -23,10 +23,6 @@ err.log
|
|||||||
|
|
||||||
# Sandbox save/load snapshots (large runtime tarballs, not source)
|
# Sandbox save/load snapshots (large runtime tarballs, not source)
|
||||||
/hh/hh-snapshots/
|
/hh/hh-snapshots/
|
||||||
# VM-library /loop artifacts — exported snapshot tars (repo-root, when `sbx`
|
|
||||||
# is run from here) + per-run logs. Generated; the VMs live in the host registry.
|
|
||||||
/hh-snapshots/
|
|
||||||
/.loop-runs/
|
|
||||||
|
|
||||||
# Out-of-tree experiments (not part of hack-house)
|
# Out-of-tree experiments (not part of hack-house)
|
||||||
/experiments/
|
/experiments/
|
||||||
@@ -35,13 +31,6 @@ err.log
|
|||||||
# Heavy / superseded demo-build kit (real demos live in video-toolkit)
|
# Heavy / superseded demo-build kit (real demos live in video-toolkit)
|
||||||
/docs/demo/
|
/docs/demo/
|
||||||
|
|
||||||
# Native-harness benchmark harness + results — dev-internal test tooling, kept
|
|
||||||
# on disk but never pushed to origin (coupled to the local tmux+podman test rig)
|
|
||||||
/bench/
|
|
||||||
|
|
||||||
# Local-only planning/design docs (kept on disk, never pushed to origin)
|
|
||||||
/docs/plans/
|
|
||||||
|
|
||||||
# Project scratch
|
# Project scratch
|
||||||
/i-try/
|
/i-try/
|
||||||
test_rsa.py
|
test_rsa.py
|
||||||
|
|||||||
@@ -1,102 +0,0 @@
|
|||||||
# hack-house — Claude operating guide
|
|
||||||
|
|
||||||
Encrypted collaborative terminal sessions with a summoned, shareable sandbox.
|
|
||||||
**Rust TUI client** (`hh/`) + **Python server & operator bridge** (`cmd_chat/`).
|
|
||||||
|
|
||||||
A Claude Code session can join a room as a **first-class member**: read/answer
|
|
||||||
humans and other AIs, and — once granted — drive the shared sandbox with full
|
|
||||||
shell + keystroke control. VMs carry a self-describing `.hh-agent` manifest so
|
|
||||||
work + memory hand off between agents (and humans), and saved VM states are
|
|
||||||
tradeable via a host-global registry.
|
|
||||||
|
|
||||||
## Operating a room — use the `hh-operator` skill
|
|
||||||
|
|
||||||
To enter/run/watch a room, bridge a Claude session into one, or autonomously
|
|
||||||
monitor and respond, **use the `hh-operator` skill** (`~/.claude/skills/hh-operator/`).
|
|
||||||
It documents the full doctrine: the daemon + `hh-bridge` CLI, the read→think→act
|
|
||||||
loop, sandbox drive (exec/write/get), the keystroke relay + stop-vocabulary, the
|
|
||||||
`watch` stop-condition engine, and the `.hh-agent` manifest for handoffs.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Run from this repo root; pin the interpreter to the venv.
|
|
||||||
HH=".venv/bin/python -m cmd_chat.operator" # = the hh-bridge CLI
|
|
||||||
$HH up <host> <port> <name> --password <pw> --no-tls # join (spawns the daemon)
|
|
||||||
$HH read --wait --timeout 30 # long-poll for activity
|
|
||||||
$HH say "…" # chat into the room
|
|
||||||
$HH keys "make build" enter ; $HH watch --for 'PASS|FAIL' --in screen # drive
|
|
||||||
$HH manifest push --root /root --name <vm> --purpose … --objective … # handoff
|
|
||||||
$HH spawn "<objective incl. the full join cmd>" --room-host … --go --skip-permissions
|
|
||||||
```
|
|
||||||
|
|
||||||
## Mobile operator on Android / Termux — the phone is REACHABLE, use it
|
|
||||||
|
|
||||||
Spec: `docs/termux-operator.md`. The operator side is pure Python and runs on
|
|
||||||
the **Fairphone-6** in Termux — it can both **join** and **host** rooms (the SRP
|
|
||||||
shim now covers the server side too, so no Rust / no `srp` C-ext). You can drive
|
|
||||||
the device directly over SSH — so **verify reachability before ever telling the
|
|
||||||
user "this can only run on-device, paste it back."** That framing is wrong when
|
|
||||||
the phone answers SSH.
|
|
||||||
|
|
||||||
One canonical, hardened invocation (use this prefix everywhere — it sidesteps
|
|
||||||
the wrong-alias trap and never hangs):
|
|
||||||
```bash
|
|
||||||
PHONE='ssh -i ~/.ssh/phone-deploy -p 8022 -o ConnectTimeout=8 -o BatchMode=yes -o StrictHostKeyChecking=accept-new u0_a203@100.95.202.68'
|
|
||||||
$PHONE 'uname -m; python --version' # aarch64 / Python 3.13.x
|
|
||||||
```
|
|
||||||
|
|
||||||
- **Reachability gate — probe the PORT, not `tailscale status`:**
|
|
||||||
`timeout 8 bash -c 'cat </dev/null >/dev/tcp/100.95.202.68/8022' && echo REACHABLE || echo OFFLINE`.
|
|
||||||
Tailscale reports `fairphone-6` **`active` even when sshd is dead** — Android
|
|
||||||
kills backgrounded Termux, taking `sshd` with it. The tailnet line is NOT
|
|
||||||
proof; the TCP probe is. If OFFLINE, the fix is **on-device** (wake the phone,
|
|
||||||
relaunch Termux, `termux-wake-lock` + start `sshd`) — say so, don't retry a
|
|
||||||
dead port.
|
|
||||||
- **Trap:** the `~/.ssh/config` aliases `phone` / `phone-deploy` point at
|
|
||||||
`100.95.180.14` (`trilluminati`), a *different, usually-offline* phone —
|
|
||||||
`ssh phone` will time out. Use the Fairphone IP `100.95.202.68` (the `$PHONE`
|
|
||||||
prefix), not the alias.
|
|
||||||
- Termux facts: Python 3.13 (≥3.11); **no `/tmp`** — `$TMPDIR` is
|
|
||||||
`$HOME/.claude-temp`; `$PREFIX=/data/data/com.termux/files/usr`; `rustc`/
|
|
||||||
`openssl` not installed by default.
|
|
||||||
- Deps that work: `pkg install python-cryptography` (avoid a rust build),
|
|
||||||
`pip install requests rich websockets`; **skip `srp`** — both client and
|
|
||||||
server fall back to `cmd_chat/client/_srp_pure` (pure-Python SRP-6a shim).
|
|
||||||
- Push-restricted work: copy this tree to the phone with tar-over-ssh rather
|
|
||||||
than a stale gitea clone —
|
|
||||||
`tar czf - cmd_chat scripts requirements-operator.txt | $PHONE 'tar xzf - -C ~/hh-mobile'`.
|
|
||||||
- Phase-0 gate: `python scripts/termux-preflight.py` on the phone → expect
|
|
||||||
`RESULT: PASS`. Operator files staged at `~/hh-mobile` on-device.
|
|
||||||
- **Proven live (2026-07-07):** phone JOINS a dev-box room; the phone HOSTS a
|
|
||||||
room the laptop joins (cross-impl SRP: laptop C-ext ↔ phone pure Verifier);
|
|
||||||
and the stdlib mobile web console (`python -m cmd_chat.operator web`) mirrors a
|
|
||||||
real room (terminal + keystroke drive + chat) in a mobile browser.
|
|
||||||
|
|
||||||
## Key components
|
|
||||||
|
|
||||||
| What | Where |
|
|
||||||
|------|-------|
|
|
||||||
| Operator bridge (daemon + CLI) | `cmd_chat/operator/__main__.py`, `bridge.py` |
|
|
||||||
| Agent manifest (`hh-agent/v1`) | `cmd_chat/operator/manifest.py` — `.hh-agent/` bundle library + CLI |
|
|
||||||
| Recursive spawn (Claude-spawns-Claude) | `cmd_chat/operator/bootstrap.py` (budgeted: `--depth`/`--fanout`) |
|
|
||||||
| Saved-VM registry / discovery | `hh/src/registry.rs` → `~/.hh/registry.json`; reader: `$HH registry list\|show` |
|
|
||||||
| Sandbox grammar (TUI) | `/sbx podman\|launch`, `/grant <name>`, `/sbx save`, `/sbx browse`, `/sbx publish`, `/sbx catalog @user`, `/sbx pull @user <label>` |
|
|
||||||
| Server | `cmd_chat.py serve <host> <port> --password <pw> [--no-tls]` |
|
|
||||||
| Rust client | `hh/target/debug/hack-house connect <host> <port> <name> --password <pw>` |
|
|
||||||
|
|
||||||
## Demo videos — use the `video-toolkit`
|
|
||||||
|
|
||||||
hack-house feature reels are produced with `~/coding/video-toolkit` (headless
|
|
||||||
asciinema-in-tmux capture via `bin/tmux-demo.py`, then a `video-forge` cut).
|
|
||||||
|
|
||||||
- **Flagship reel — three Claudes, one shared VM:** `scenarios/hh-vmhub.json`
|
|
||||||
(capture) + `scenarios/hh-vmhub-cut.json` (forge cut). A planner, builder, and
|
|
||||||
tester (each a real nested `claude -p`) collaborate to build **VMHub** — a
|
|
||||||
GitHub-for-VMs web app — live inside one shared sandbox, then save it to the VM
|
|
||||||
library. Role task-scripts: `scenarios/vmhub-{builder,tester}-task.sh`; staged
|
|
||||||
app under `scenarios/assets/vmhub/`.
|
|
||||||
- A reel must **show the product**: the Rust TUI room (roster, encrypted chat, the
|
|
||||||
shared sandbox F2 view) with Claude visibly operating as a member and
|
|
||||||
Claude-spawning-Claude — not just a console of CLI calls.
|
|
||||||
|
|
||||||
> Provisioning note: the demo summons a pre-baked `localhost/hh-dev:slim` (python
|
|
||||||
> 3.11) podman sandbox so VMHub (stdlib, zero pip deps) runs with no installs.
|
|
||||||
|
Before Width: | Height: | Size: 682 KiB |
|
Before Width: | Height: | Size: 752 KiB |
|
Before Width: | Height: | Size: 273 KiB |
|
Before Width: | Height: | Size: 271 KiB |
|
Before Width: | Height: | Size: 200 KiB |
|
Before Width: | Height: | Size: 274 KiB |
|
Before Width: | Height: | Size: 946 KiB |
|
Before Width: | Height: | Size: 711 KiB |
|
Before Width: | Height: | Size: 344 KiB |
|
Before Width: | Height: | Size: 1011 KiB |
|
Before Width: | Height: | Size: 641 KiB |
|
Before Width: | Height: | Size: 601 KiB |
|
Before Width: | Height: | Size: 423 KiB |
|
Before Width: | Height: | Size: 582 KiB |
|
Before Width: | Height: | Size: 560 KiB |
|
Before Width: | Height: | Size: 852 KiB |
|
Before Width: | Height: | Size: 760 KiB |
|
Before Width: | Height: | Size: 316 KiB |
|
Before Width: | Height: | Size: 1001 KiB |
|
Before Width: | Height: | Size: 699 KiB |
|
Before Width: | Height: | Size: 826 KiB |
|
Before Width: | Height: | Size: 418 KiB |
|
Before Width: | Height: | Size: 363 KiB |
|
Before Width: | Height: | Size: 134 KiB |
|
Before Width: | Height: | Size: 680 KiB |
|
Before Width: | Height: | Size: 740 KiB |
|
Before Width: | Height: | Size: 857 KiB |
|
Before Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 183 KiB |
|
Before Width: | Height: | Size: 197 KiB |
|
Before Width: | Height: | Size: 763 KiB |
|
Before Width: | Height: | Size: 602 KiB |
|
Before Width: | Height: | Size: 269 KiB |
|
Before Width: | Height: | Size: 259 KiB |
|
Before Width: | Height: | Size: 307 KiB |
|
Before Width: | Height: | Size: 304 KiB |
|
Before Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 197 KiB |
|
Before Width: | Height: | Size: 123 KiB |
|
Before Width: | Height: | Size: 192 KiB |
|
Before Width: | Height: | Size: 190 KiB |
|
Before Width: | Height: | Size: 155 KiB |
|
Before Width: | Height: | Size: 413 KiB |
|
Before Width: | Height: | Size: 386 KiB |
|
Before Width: | Height: | Size: 382 KiB |
|
Before Width: | Height: | Size: 419 KiB |
|
Before Width: | Height: | Size: 783 KiB |
|
Before Width: | Height: | Size: 328 KiB |
|
Before Width: | Height: | Size: 296 KiB |
|
Before Width: | Height: | Size: 694 KiB |
|
Before Width: | Height: | Size: 222 KiB |
|
Before Width: | Height: | Size: 610 KiB |
|
Before Width: | Height: | Size: 368 KiB |
|
Before Width: | Height: | Size: 159 KiB |
|
Before Width: | Height: | Size: 194 KiB |
|
Before Width: | Height: | Size: 332 KiB |
|
Before Width: | Height: | Size: 701 KiB |
|
Before Width: | Height: | Size: 559 KiB |
|
Before Width: | Height: | Size: 579 KiB |
|
Before Width: | Height: | Size: 671 KiB |
|
Before Width: | Height: | Size: 624 KiB |
|
Before Width: | Height: | Size: 224 KiB |
|
Before Width: | Height: | Size: 820 KiB |
|
Before Width: | Height: | Size: 194 KiB |
|
Before Width: | Height: | Size: 291 KiB |
|
Before Width: | Height: | Size: 875 KiB |
|
Before Width: | Height: | Size: 607 KiB |
|
Before Width: | Height: | Size: 731 KiB |
|
Before Width: | Height: | Size: 340 KiB |
|
Before Width: | Height: | Size: 282 KiB |
|
Before Width: | Height: | Size: 240 KiB |
|
Before Width: | Height: | Size: 312 KiB |
|
Before Width: | Height: | Size: 314 KiB |
|
Before Width: | Height: | Size: 339 KiB |
|
Before Width: | Height: | Size: 851 KiB |
|
Before Width: | Height: | Size: 765 KiB |
|
Before Width: | Height: | Size: 766 KiB |
|
Before Width: | Height: | Size: 817 KiB |
|
Before Width: | Height: | Size: 681 KiB |
|
Before Width: | Height: | Size: 916 KiB |
|
Before Width: | Height: | Size: 802 KiB |
|
Before Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 242 KiB |
|
Before Width: | Height: | Size: 629 KiB |
|
Before Width: | Height: | Size: 158 KiB |
|
Before Width: | Height: | Size: 271 KiB |
|
Before Width: | Height: | Size: 334 KiB |
|
Before Width: | Height: | Size: 724 KiB |
|
Before Width: | Height: | Size: 586 KiB |
|
Before Width: | Height: | Size: 328 KiB |
|
Before Width: | Height: | Size: 805 KiB |
|
Before Width: | Height: | Size: 776 KiB |
|
Before Width: | Height: | Size: 187 KiB |
|
Before Width: | Height: | Size: 414 KiB |
|
Before Width: | Height: | Size: 554 KiB |
|
Before Width: | Height: | Size: 515 KiB |
|
Before Width: | Height: | Size: 695 KiB |