From ff92d812ad90cfa07d44441011179570723cdb97 Mon Sep 17 00:00:00 2001 From: veg Date: Sat, 4 Jul 2026 14:41:43 +0000 Subject: [PATCH] docs: state the accidents-not-adversaries threat model; add ROADMAP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The gates in front of destructive operations exist to stop mistakes (stale rosters, typos, racing hosts); stopping a malicious group member is a side effect, not the design goal. Written into README §Security and the man page so future checks are judged by that bar. ROADMAP.md captures the direction: social features (knock, log, clean) over further hardening, plus the explicit resist list. --- README.md | 2 ++ ROADMAP.md | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ party.1 | 10 ++++++++++ 3 files changed, 63 insertions(+) create mode 100644 ROADMAP.md diff --git a/README.md b/README.md index 6093960..d9e8fd7 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,8 @@ The mechanism is identical everywhere: group ownership and mode bits plus `tmux `party` assumes you already know and trust everyone you add to the group; it is not a public access-control system. Both gates above protect each party, and the **auth gate** (`tmux server-access`) is authoritative, with the filesystem gate as defense in depth. +The threat model is **accidents, not adversaries**. `party` runs where everyone already shares the box, so the ownership and symlink gates in front of destructive operations (`close`'s directory removal, moderation) are there so a stale roster, a typo, or two racing `party host` invocations can't remove or hijack the wrong thing — that the same checks would also stop a malicious group member is a side effect, not the design goal. New checks should earn their place by preventing a plausible *mistake*, not by closing a hypothetical attack from a friend. + Three honest caveats, with the full detail in `man party`: - On ACL-enabled filesystems (ZFS, HFS+/APFS), inherited ACLs can override the mode bits, so the FS gate is best-effort. The auth gate still holds. diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 0000000..9f8643a --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,51 @@ +# Roadmap + +Direction, not promises. Two rules govern everything below (README +§Security has the long form): + +- **Accidents, not adversaries.** New checks earn their place by + preventing a plausible mistake — stale state, a typo, a race — not by + closing a hypothetical attack from a friend. +- **Social, not mechanical.** New features earn their place by + encouraging people to work together in a terminal, not by adding + machinery. + +## Next — small, high value + +- **`party knock `** — an uninvited group member pings the host + via `write(1)`: "veg wants to join fiesta". `party list` already + shows invite-only parties; knock completes that loop. The feature + most likely to cause spontaneous pairing. +- **`party log`** — per-party transcript via `tmux pipe-pane` into the + per-party dir (group-readable so every attendee can grab a copy); + `party log --stop` ends it. "What did we do last night?" for + collectives, and the audit trail human+AI co-work needs. +- **`party clean`** — remove the caller's own crash leftovers (dirs + they own whose socket is dead), turning the manual `rm -rf` recovery + in host's error message into a verb. + +## Later + +- **Group ergonomics** — the default `party` group needs root and a + relog before anyone's first party. On boxes where everyone already + shares a group, `host` could offer (or default to) the caller's + primary group when `party` doesn't exist. Fits the trust model; + costs a little existence-confidentiality. +- **One liveness primitive** — fold `is_party_alive` into + `party_conn_state`; two concepts where one would do. +- **Matrix** — live validation on NetBSD and DragonFly; one + interactive attach/role/switch pass per release (automated coverage + is all non-interactive). + +## Resist — by design, not by neglect + +- **No network transport.** Same-host is the perimeter; beyond it lies + reinventing ssh. +- **No per-pane ACLs.** tmux can't enforce them; faking it with hooks + would be a leaky abstraction. Document the limitation instead. +- **No config files, no plugin system, no ACL syscalls.** One POSIX + file that runs on a 30-year spread of UNIXes is the identity; the + 2026-04 simplification that removed per-OS ACL dispatch is not to be + unwound. +- **Watch the file size.** Heavy why-comments are a feature; feature + growth that pushes the single file far past its current size is not. diff --git a/party.1 b/party.1 index 114c207..0c02314 100644 --- a/party.1 +++ b/party.1 @@ -356,6 +356,16 @@ A group member who plants a forged directory cannot fake its ownership, cannot redirect the socket path, and cannot forge a socket elsewhere. .Pp +The threat model is accidents, not adversaries. +The ownership and symlink gates in front of destructive operations +exist so a stale roster, a typo, or two racing +.Cm host +invocations cannot remove or hijack the wrong directory; that they +would also stop a malicious group member is a side effect, not the +design goal. +New checks should prevent a plausible mistake, not a hypothetical +attack from a friend. +.Pp .Nm is designed for small, mutually trusted groups: a hacklab, a tech team, a circle of friends, not strangers across the internet.