Bivouac Wiki is web-of-trust decision software. The name comes from mobile ant nests composed of living members.
Ornithopter is a small business that provides managed hosting for it, however it's open source and you can run it yourself.
There are lots of goals for this software - but for now we're going to build out single-site polling, and slowly expand into the rest of the features.
What do you do with it?
weird, distributed playbooks and wikis with voting. Like if HomeAssistant.io automation playbooks were distributed and had voting. Or like Loomio, but federated.
Bivouac is a petname (& fediverse) based software & grammar for managing decisions across computers (hopefully in a healthy way).
For example, say you're a worker-run cooperative, a union, a volunteer project, or another form of collective or confederacy.
Maybe you have some decisions that you'd like to make as groups or as smaller teams? - This software allows those kinds of building blocks to happen, it's a governance sandbox.
We include an example for configuring meta-moderation via bivouac decisions. You could build your own complex governance playbooks.
Quick Overview
This is 8 things in a trench coat.
It allows you to define a group of users (called Crews); create roles within that group, assign permissions (called Mores), and define Choices which are governance templates for deciding actions. Those actions could be in the group software itself, pointed at other software, or manual actions.
Bivouac documents (called Bloat) are created on an editor (that you can run on your laptop or in the cloud). The documents are then published on a static hosting provider, where other bivouac editors can download and review them.
Users and groups adopt handles (username strings): users with one @, groups with two @@. These handles only have meaning when speaking about a particular network graph of friends; they aren't globally reserved and multiple people could have the same handle. Bivouac understands both Fediverse handles (@username@some-domain.com) and its own petname handles, called Phish.
Documents can be tagged by users to collections managed by curator roles, and the curator and author can separately choose to display the tag relationship (called Decals). This form of group-curated tagging is similar to Danbooru, an image tagging software. Unlike hashtags, which are globally namespaced, the curators of a tag can describe a tag with a short sentence, and it links to a longer article about the tag.
Users can configure how their feed is displayed, when they're notified, and even delegate their voting power temporarily (a concept called Liquid Democracy). Groups can specify in decisions how this kind of delegation power is regulated in a decision (for example some vote might disallow delegation, or require you volunteer). These choices are configured in Syzygy documents.
Some things this is not...
there's a particular "type" from Web3 and it's not welcome.
Bivouac has some rather odd design decisions giving it a unique flavor. It's meant to be more hospitable to community and less hospitable to bad actors. Rather than unanimous bandwagons, it's meant for allowing dissent and deviance to be expressed in a healthy way. As with any well-run software project, it does not give space for bigotry. Fascists, racists, transphobes, etc are not welcome voices on decisions.
With the web chock full of bitcoin and blockchain pump and dump schemes, it seemed like a good idea to build a reminder of what being outside the box should be like. f--- bitcoin/blockchains. This is just one silly project. It's more like torrents or indieweb, and we plan on making it compatible with ActivityPub (more on that later!). It's sharable, forkable, mirrorable, but it also embraces components of the old web, like running your own blog or talking to someone on an open protocol (AP would be preferred).
In contrast to DAOs, we make no grand assertion that humans can be entirely removed from the mix (your organization should still have a physical existence and/or a system administrator).
This software might occasionally get stuck and need someone in your group to manually fix it. That's fine; the decision and counting systems and state should all be pretty readable (flat XML files).
As with many problems, they can't all be fixed by software, it takes good volunteers, good moderators, with tools built by developers who listen to them. Sometimes it's better to focus on building good moderation tools.
Re: Premature Optimization
Forward to the nerds
<3
Bivouac is not production grade, it's not a PhD thesis in anonymous voting or ring cryptography (this is plaintext voting, NOT a secret ballot). It probably doesn't stand the test as far as distributed systems serializability, it's not a MVCC or CRDT. It wouldn't stand up next to TUF, Sigstore, or Signal. It isn't the coolest petname system.
So, with that apology in advance to people who actually know stuff; if you are really good at distributed systems or cryptography, my condolences to your sanity. This best effort plaintext state engine is gonna be painful.
Still, it could be interesting to see how many bugs this has.
It's our hope that this can illustrate some forms of governance and collaboration that become possible in the digital world at different sizes of groups.
Re: ActivityPub
Doing AP correctly is hard.
Bivouac's whimsical focus initially started as a static site generator ("serverless" in the way that Sqlite is serverless, not the AWS kind). You could even theoretically toss around USBs among friends of Bloat documents.
As bivouac gets more defined, the particular ActivityPub grammar extensions needed to "bridge" the two can be proposed. Some items are relatively straightforward like nodeinfo or webfinger.
ActivityPub is much more complicated than "just RSS with push notifications". However, it's the one protocol that would be nice to bridge to (not bridging with ATProto, Veilid, Holo, Zeronet, etc).
Other parts of AP posts don't entirely allow for the same logical evaluations, but that's not a bad thing. Bivouac could run some groups or decisions in a reduced functionality mode meant for fediverse bridging. For example: Fediverse clients don't have encrypted messages so the decisions would be plaintext ActivityPub JSON.
AP has the most promise to fully encode decision and group logic entirely within itself - for example FEP-2100 details groups that are unbounded by servers. There are some components that could also be superficially connected, like MetaGov's governance gateway to OpenCollective. Logging in via AP is another FEP-d8c2/FEP-61cf. Other open protocols like supporting CalDAV for your native calendar application would be nice, or native RSS for rendered HTML sites.
Bivouac could run in local-only mode, fedi-only mode, bloat-only mode, or bridged. This also might be configurable per group.
With that out of the way, check out the other sections!
Initial Feedback
- no consistency model
- will work on this later, want to get initial buttons/forms/algorithms in play and revisit MVCC or CRDTs or git-style merging
- vaporware
- this is my worry (not finishing the demo app)
- maybe a demo would help explain it?
- you got it!
- have you seen Nostr/Holo/Tahoe-LAFS/etc?
- yeah, but I wanted this to be more indie-web-ish and activitypub-ish.
Bloat: message encodings
Messages in native bivouac are represented as XML documents. For bridged AP discussions they will probably have a JSON-LD format equivalent that is then interpreted into an unsigned/unencrypted copy in memory, for use by further layers of the software.
Bivouac's subsystems have their own dialects and syntaxes, the file extension clues you
into that, for example alice.phish
is a Phish identity document.
Private Sqlite, Public XML
State in bivouac is represented as static files left on static HTTP servers. Anything that's meant to be private should be kept in sqlite, for example users' emails on an editor, their passwords (in argon2id) or API keys to an Action.
Emails and keys and such should never be synced across instances, and any state in XML is assumed to be possibly accidentally made public. Any state in sqlite is assumed to be private and needs to be guarded as such. This means that there is only one copy of the sqlite data, if that host is offline or unrecoverable that data is gone.
Message Wrapping
Messages on bivouac are XML, which is then signed with Minisign, a small and simple verification program. This is then encrypted for the Crew recipients with Age - a similarly simple program built by professionals. Phish identities correspond to a pair of these keys (your Minisign and Age public key). XML signatures do exist but... so do XML schemas and I hardly understand those, either.
Documents should be password encoded, and then the list of documents' passwords can be encrypted to a Crew of Age recipients. That way adding or removing a member of a group does not mean re-uploading every single file, but instead providing that member with the passwords to the files.
Server Addresses
Once the files have been rendered, the folders you've generated should be published on a static HTTP server (like Caddy). Bivouac's editor needs permission to upload files (for example, FTP or SSH creds).
Bivouac content does not need to be at the root level (/
) of the website. You could, for
example, publish on /cool/beans/
. Bivouac discovery and hints are covered in Phish.
If you own a clearnet domain, you may use that. You can also publish to a hidden .onion Tor website (Bivouac helps generate the configuration for you). Given how Phish identities work, it's okay for it to be on a random website.
Documents and folders may be configured to be behind HTTP basic authentication. Bivouac will help you generate configuration files to enforce it, and editors can be configured to enter the HTTP credentials when needed.
Servers should not block connections from Tor, as bivouac is configured to optionally download content via proxy (recommended). Bivouac is not meant to be directly peer-to- peer and instead recommends publishing content on public servers or via Tor.
Running in ActivityPub mode does require that you have a domain on the clearnet, with the bivouac editor itself receiving connections. This does expose it to more risk compared to the static file uploads model.
Webmention Introductions
Bivouac can discover new servers by reading peer's content, but others can also introduce their blog to yours.
This functionality requires the ability for you to read your server's logs. Some cheap static site hosts do not let you do this. It's similar to webmention, an indiweb standard for notifying a blog author that their page was linked to.
It's a base64 encoded bloat document, in a query string, introducing your Phish identity. It's then up to you to decide whether your blog should network with theirs.
The Editor
Edits (prior to uploading to a static site) are conducted via a server-side JS-free program for simplicity sake. A nicer editor (perhaps a native one) could be built with auto-complete and other features (like WYSIWYG).
In the current model, browsing documents in the editor can open up new tabs for complicated interactions. For example, delegating a vote might open up an HTML form with menus, buttons, and other information.
You may choose to self-host your editor and thus edit from http://localhost. You might also choose to keep it on a site behind a VPN for your users, or you might make a public site anybody can sign up to. Or, keep it on your own box, that also works.
Your private keys are stored on your editor (if you don't want a website to have your keys, run it on your laptop and then upload the results). Bivouac does not store the passwords to your Age or Minisign keys at rest, but does temporarily use them to do work on your behalf.
I would be fond of being able to use Age and Minisign keys in bivouac from hardware yubikeys (e.g. age-plugin-yubikey and minisign-fido).
Rendering
Documents in bivouac exist as XML, however wiki documents may use markdown inside text boxes, for human readable references. Bivouac tries to resolve any referenced handles (this is discussed more in Phish) - but can also create stub articles for you to finish in a new tab.
Bivouac also renders content to a public representation in static HTML. These HTML renderings present content from the perspective of the mirror host, in contrast to the XML documents which present things like petnames from their first-person author perspective.
The HTML documents can be extended through templates, and can link to ways for users to participate either on your groups' editor, or on their local laptop. Even without bivouac you can still browse the decisions being made (so long as they're addressed to a public Crew as an observer).
Carriers
A server that a Phish identity controls is called a "Carrier". These are, for example, personal blogs.
A special kind of carrier is a custodian, someone who has the responsibility of the group to maintain documents (where other people are off the hook). You are also the custodian of your own content. (this is different from a curator, which is discussed later in Decal)
Venues
A server someone is comfortable having their content mirrored on is called a "Venue". These could be group-run servers, or other friends.
Your direct friends and collaborators are probably okay with being venues for your blog content, but you can ask!
Mirroring
Messages, identities, groups and decisions can exist on many servers at once (just like torrented files).
If a person's venues or carriers go down, so long as they get back in touch with their buddies (with webmention or just on the grapevine), it's like they hardly left. This is in contrast to a mastodon server dying and taking identities with it. Just like those ants, home is where your friends are (this is more apparent in the next section on Phish).
Sites decide what content they mirror. A key difference between this and "free speech"- ish systems is that the encryption should not be blind to the site host. It's recommended that you not mirror that which you are not able to decrypt.
Dual ID and Petnames
Bivouac supports two styles of identity: fediverse, and petnames. A petname is a solution to Zooko's triangle, the trilemma that it's hard to have something be simultaneously human-meaningful, secure, and decentralized.
Bivouac petnames have meaning based on what a peer gives a name, they're a bidirectional relationship between keys and names. Spritely's take on this is pretty nice.
Phish names are non-global and thus not prone to cybersquatting. Value in a name should come from the friends, not from some Namecoin or cryptographic mining or DNS registry (which cost money or are complicated for end users). They only need to be unique to the friend or group.
They're potentially private (it's a preference you can set in syzygy), but sharing them with others allows you to build a graph of names, and build trust. It also allows you to find your friends again if you're lost.
You can simultaneously have a Fediverse handle and a Phish petname, they could match or could be different.
Character Restrictions
Markdown in bivouac looks up bivouac and fediverse handles based on a defined syntax.
Fediverse handles take the form @user@domain.com
, where Phish identities use
@someone.else.phish
. The pseudo-TLD .petname
was also considered but would be long.
Handles are composed of the characters [a-zA-Z0-9_-]
. They may not use the
characters :
, #
, .
, or @
.
Web of Trust
Say you don't directly have a petname for a user, but a friend-of-a-friend does. In bivouac, so long as a user has a path to us, we can render an approximate name.
To do this, we order the friends along that path:
@"kevin".phil.dave.peter.alice.phish
Canonization
When an identity has not been confirmed by you as a user, we call that an "un-canonized"
name (aliases you have not accepted are kept in quotes). Identities in
bivouac are hyperlinked to a page where you can interact with them, for example to
follow them. You can also canonize their alias, either freezing the long handle or
creating a direct handle (@kevin.phish
). Canonized names must be unique to the
person who decides to canonize them (this will be more clear in the section on Cicada).
Where a user has both a fediverse and a petname, they are rendered together (in
whatever order you like), for example @alice@cool.computer|@hacker_alice.phish
.
Verification
Identity is mostly trust on first use, however there are a few niceties thrown in.
Bivouac can understand references to Fediverse identities. For example, on mastodon
you can set a link in your profile to your blog, and as long as your blog includes a html link tag
rel=me href="your-mastodon-account"
, you get a "verified" checkmark on many
clients. Similarly, Bivouac understands if you have linked a blog to both your mastodon
and your bivouac usernames. A HTTP URL referenced in your phish doc that's on your
blog, that contains your phish doc suffices. It also should eventually support ariadne.id
and keyoxide.
You also have the graph of what your friends' friends call someone, and what aliases they have selected as a preference for their handle.
A user's page might express their health in terms of:
- whether you were able to reach their carrier sites recently
- whether they have good Karma
- whether their NS peers were reachable
- whether you cannonized their name
- whether their group agreed on the cannonization
- whether they're in a ban list
- recent posts and activity
- their fediverse handle
- their keyoxide ID and any verifications
Changing Key Records
the part that Soatok might think is just awful
Bivouac keys include one mechanism for changing them, that of "nameserver" records. For people unfamiliar with DNS, a nameserver is the place one asks for where a domain can be found (it's the root of their identity).
In Bivouac you can define a list of either:
- a DNS TXT record (containing your phish record)
- a HTTP URI (containing that file)
- or another Phish friend you trust,
as the "nameservers" of your keys. This list of people each can be assigned a weight, and the name itself assigned a threshold, where reaching it means other clients will accept the key change. It might be possible to even define a Choice playbook for whether friends should trust the old or new name yet.
The HTTP URI or TXT records might be things you control, or might be set somewhere else.
For example:
- alice
- my blog:
http://something.onion/abcd/
- my Age key: abcdef...
- my Minisign key: abcdef...
- my NS record threshold: 8
- my NS records:
- 1: DNS: foobar.alice.com, weight 10
- 2: DNS: coolstuff.blog, weight 3
- 3: Phish:
@phil.phish
, weight 5 - 4: HTTP:
https://mastodon.com/@some_user/post132
, weight 5
- my blog:
In this example, either Alice changes their DNS record, or both Phil and @some_user change their data.
Note that the old records might lag during a pending change (e.g. they might have 10 votes in the wrong direction) - Phish NS changes are important for your NS friends to update very quickly. This allows documents to continue to be addressed to you, and allows your Crew memberships to be updated quickly, etc.
Phish identities also define a TTL for refreshing, and a TTL for contacts to re-verify using a human action.
When the threshold to change a key is reached mid sync-cycle, the newer key AND the older key are referenced by default (encrypting to both, or allowing signatures from both), while human intervention is pending. This allows for documents in other folders mid-change to still be valid or seen by you if you're mid-keys (however only one key is valid for a vote or edit at a time, it just might be different on different hosts). Some of this is explained more in Cicada, and some in Bivouac's state machine. How you update identities or the steps your friends update identities with (for example using Syzygy) should be visible to both of you as parties.
Out-of-band verification
Phish isn't as cool as real systems for federated public key management. It still expects that you can actually reach the people you've given petnames to in person or via another means outside of bivouac.
That human action should be defined between you both in a friend/note memo on the profile (for example: on key/address change, verify out-of-band with me in person).
This human verification should DEFINITELY be done by those who are named as nameserver peers, and should Probably be done by those who aren't.
New Names
Phish aliases can be changed, this notification goes to your friends who can then update their petname tables and accept the new nickname. Note that since it has to be unique on anyone's list, Bivouac can quickly check your friends to see if they already canonized someone with that handle.
Keeping in touch
Finger tables, neighborhood maps
Rendering editors keep tabs on changes to identity records and will helpfully try to keep you from losing touch with friends, even if you haven't read your mail in a while and approved the new identity or address yet.
It keeps around a loosely up-to-date document similar to a "finger table" - except it's purposed for web-of-trust lookups. This isn't exactly like Kademlia or Chord DHT's finger tables (which are actually random and uniform) - and is instead based on how many hops away someone is. We call this the "neighbor map", and users can choose to opt-out of it.
Bivouac keeps tabs on:
-
- your nameserver Phish friends (always)
-
- any first-party article authors you've saved or canonized (anytime you're working on stuff)
-
- their second-party-connections (retrieved from 1sts)
-
- the 4th connections (retrieved from their 1st's next list)
-
- the 8th connections (retrieved from their 4th's list)
I might be slightly off by one but you get the picture. On visiting any of those indexes one could then jump peer by peer to reconstruct a valid list and hopefully get in touch with someone who knows where your friend went.
Network Repair Mode
Typically Bivouac will do this through osmosis by reading the first party article author's files. When a degraded social graph is detected, it might reach out one by one (to 1,2,3,4,5,6,7,8 steps away). It may keep as many connections in the neighborhood map as you're comfortable with storing.
If a new document is found that references an identity your editor didn't know, a finder
subroutine can be started. Typically enough starter information should be in the
document itself (depending on how old the document is, for example if they changed
HTTP servers). Bivouac can also go actively hunting for that author, or just passively wait
to fill in the details later. If an ID isn't known at all, it's rendered as quotes even up to the
.phish part, for example if I haven't checked that alice's NS peers are actually online, or
that dave is even a live ID, @"dave.alice".phish
would be how it'd render.
Pinning and Following
what bivouac keeps around
In bivouac, your editor caches the things you mention you want to stay up to date on. Then, when edits come in (like a friend changing servers), it will helpfully keep them fresh and up to date locally.
Bivouac will download the new version and wait for you to approve replacing it in the cache (next section). As discussed in cicada, it does not have to immediately mirror the new version unless configured to.
Bivouac doesn't /have/ to go see the source document on a source server, and could pick from any random mirror. It first checks the indexes for any updates (cicada explains this).
Next-of-kin
Groups define a "succession" process, but phish identities define a similar thing, a "next of kin" process, to either recycle, memorialize, or takeover a petname. You might also decide that nobody is allowed to apply for certain names.
ActivityPub has a similar thing for either transferring a handle between servers or otherwise deleting a username.
Not Always Online
Bivouac does not assume every mirror, editor, or user is always online. Instead, members of a Crew opportunistically mirror from their friends blogs. For most decisions there will be some defined techie or administrator who tallies up votes and is the primary mirror or custodian venue, so the rest don't need to keep documents around.
Similar to cicadas, this requires the hapenstance that you and your friends' blogs happen to be online at the same time. Syncing USBs of folder content is probably feasible too (as with a sneakernet).
Group updates in bloat mode are much slower than what you're used to in fediverse PubSub. A site rendered once a day might complete a sync and decision cycle in a week.
Venue/Carrier health
Venues and Carriers' health can be expressed in a few states:
- dead - unreachable for longer than expected
- pending - they have changes
- quiet - they don't have changes
- broken - unsolvable zipper state or key we can't find
This can be viewed in a network health table.
Synced Topics
the part that will probably disappoint Aphyr for not being serializable
Folders in Bivouac's cache are initially random identifiers (UUID v4). In database jargon this is a surrogate key. If you do have a name for that folder (for example, the identity documents for @alice), during the sync and render phases the cannonized files become naturalized. These UUID folders are called "synced topics".
You may optionally use the same UUID4 IDs as the server you download from, but you may just as easily rotate them (e.g. on malicious conflicts). If you canonized a name, it could be rendered into a folder named the same thing, for example "/alice/".
Documents also have an internal UUID4, used by the author (that should be unique to the author). The folder could use the same UUID, or something else.
Meaning is derived based on what the peers in the group name things, not what folder the XML is in (the published site could be a random layout, as long as your editor can find the cicada files to download what matters).
Lists of content, recent changes, and the sync state of the group are detailed in .cicada
files in the folders. These are like torrent files, detailing the name, size, and SHA256
hashes. A CRDT or MVCC system might be smarter but this is good enough.
Document Lifetimes
Cicada documents detail in units of days:
- how long the files should be kept around (lifetimes)
- how often you should check for changes (cycles)
- how long each step in a process lasts (phases)
If a network partition persists, eventually nodes that have a file meant to have been deleted will move past their expiry time and should discard the half-unused file. Files that should stick around should be kept by at least one custodian venue.
Some documents are constantly renewed (like Phish or Crew documents). Others, like Decisions or Cicada changelogs, are slowly erased with time.
Temporal Operation Precedence
Deletions are noted in the cicada index but no tombstone file is kept.
- Last write wins
- Update wins over create
- Create wins over delete
Some topic folders might depend on other topic folders. Right now folders are flat rather
than nested. For now I'll point out that the permissions documents (the Mores
file
extensions) folders matter more than, say a decision document, and evaluate first during
rendering. Newer Phish
documents are similarly explored to find out if the new phish
keys were used to sign a pending document, for example.
Mods do have temporal powers to re-order, delete, or request replacements for documents if the sync zipper gets stuck. These temporal powers are used for example by Facilitators of a debate if any sort of human edits to an option need to be made to unstick the process. If a mod writes a cicada patch to reorder or insert something, their document ordering is the one that counts.
Sync Zipper
Sync is eventual, lazy and optimistic (creation, propagation, scheduling, conflict resolution, commitment). If a client is completely offline for a decision and didn't delegate their decision, they miss it. You can imagine sync like many simultaneous zippers that are in the process of individually meshing:
- the far ends we don't know about (drafts on other people's machines)
- (share) the ends they've published, and we've yet to download (parts of the zipper we can see)
- (receive) the known files, ordered in the time they were published (just before the zipper)
- (order, conflict or accept, certify, act) the files as accepted and applied (this is the state any sort of permissions/Mores access control lists or Karma are evaluated on)
- files that we're not presently applying, but still depend on for some reason
- files that are deprecated but still here on some custodian's server (in case someone who missed things might get lost) - other zipper end opening
- files that are getting deleted
Two phase commits (commit/abort votes), locks, rollbacks, MVCCs (read/write timestamps), & CRDTs are not considered here. It is approximately last-write-wins.
Where proof of a timestamp or receipt is needed, rather than rely on signed timestamp servers (e.g., RFC-3161 whatever), we ask a node to countersign a document a day or so later. This countersigning is also useful for noting the position of other servers' Cicada zippers (to know who to download what from).
Current, Pending, and Deprecated
Bivouac's cache and published sites have three subfolders: current, pending, and deprecated. Any pending file includes the user's current minisign public key fingerprint as part of the filename (for example, only one selection vote can be made per user on a vote, or only one NS change option can be made per user).
If the "pending" folder is empty, the topic is said to be "quiescent". If new changes exist, that's like having the zipper need to zip upwards to finish being in sync. Once it is, the bottom of the zipper can unzip and older state can be forgotten.
We only need to keep around the agreed upon current state of a folder during a quiescent cycle. Note that something might depend on many folders (for example, a folder of rules for this election, another folder for members of the electorate) - so that's why some files might still be needed for another purpose across the group.
For example, an election might contain a phase where an election is proposed, but needs enough signatures. Then, it might need a phase for candidates to get signatures. finally, people need to vote on candidates, and the results are tallied.
The authoritative state machine(s) are operated on a specific user's box, but other members of the group can be observers in some cases. This is explained more in the final bivouac section.
Cicada will not sync files in your salted deny list tags (more on those in Decal).
Torrent Super-Seeding
Cicada can include definitions for super-seeding, just like torrents. For example, if you have 8 documents, you can start by sharing a cicada file to each friend detailing one of the documents, and they mirror on day one. Next, on day two they ask their other friends (if they're online) for the other docs. Maybe they're lucky and can assemble everything. Or, you've updated your cicada doc for each friend and now list 2 docs for each friend. If it's up to the clients, they'll try to sort randomly and evenly/opportunistically download from many.
Caching is not Mirroring
Just because a file is synced to your device for review does not mean that Bivouac will mirror it publicly on your site. You need to define or approve per folder or group (etc) whether something should auto-mirror or whether it requires your approval (or a specific amount of karma or specific tags to not be present, etc)
If you don't know a lot about a group, you can download the group's cicada file. If you're after particular decisions, you can download just their update files.
You can optionally mirror the known state/cicada file of other servers (for example, noting that another server claims to have specific portions or is caught up to a specific cycle or phase).
Groups in Bivouac are loose collections of users defined in Crew documents. Group names are non-global and groups can be forked.
Groups in Bivouac are noted with a double @ sign, like @@coolhackers.alice.phish
.
Groups have special meaning as they can contain roles within them, that can manage
decal tags and group decisions.
Users may apply to join a crew, or be nominated as such, and with receipt of the other party's acceptance to the role (countersigning), compliant editors will bestow on them the relevant permissions or duties (see that in Syzygy's notifications/feeds).
Membership Proof
You can enforce membership using things like OpenCollective or SSO (similar to how Fulcio works). These membership types are checked by one machine, which then signs the membership statement and it's trusted by the other machines.
Where Are Crews
Crews define their allowed and preferred venues for Cicada to sync.
Crews aren't necessarily on a particular server, but they're probably rendered to a preferred one. It's probably run by your resident nerd.
You can find a crew's location by knowing one of the friends who are in it, because their editor will keep tabs on the venue the crew is at.
Roles
Roles in Bivouac are handles prefixed to groups, like @mods@@coolhackers.alice.phish
.
A role can have many permissions referenced in a group's Mores documents. Mores are
used to allow or deny changing Cicada and Bivouac states based on the privileges of the
roles.
Documents in bivouac are not typically addressed 1:1, but are encrypted for a group of people. For example, in a team decision about whether to go to the east coast or west coast conference. A rendering editor refers to the crew list (containing a list of Phish identities) to determine membership.
Succession Planning
Roles can also define succession planning, for example specifying who becomes admin if no admin logs in for a month (in a flow decision). However, groups can also be easily forked (provided the other members go along with you in a rebel flow decision).
Built-in Super-Roles
Admins of a group may create roles (or this may be initiated by a Bivouac choice template) as they see fit, but some hardcoded key roles do exist. They are:
- root - the one who renders on a particular blog (the sysadmin)
- admin - the superuser of a group
- mod - a subclass below an admin of a group (typically affecting Karma and appeals)
- curator - those who curate a tag and can approve/deny them
- facilitator - those who moderate a decision
- debater - those who can propose options for a decision
- voter - those who can make selection documents about a choice
- observer - those who can see options/debate, but not votes
- auditor - those who count votes and know who voted for what
- evaluator - those who are notified by the auditor of what action to take (and typically have API credentials to make other things happen)
- petitioner - those who can initiate a choice
- candidate - those who want to be or can be a representative
- representative - those who are delegated power from others
If a role's Mores document contains effectively those permissions or is somehow involved in those decisions in some capacity, editors should label the profile role as containing those classes of effects.
Mores, from "Social Mores", are documents that define the relationship based access control (ReBAC) for a group (or even relationships between groups). It also defines how user Karma works.
Users can be members of several roles, and interact with many processes. A Mores document defines the actions a role in a group can take. It also defines what rules and roles from other groups will be respected and how.
Mores and karma can be changed through flow-based playbooks (discussed more in the Bivouac section). Things like meta-moderation are also possible.
Rule Precedence
When evaluating a pending change to the bivouac state, the program considers:
- the "overrides", the group rules that take priority over all else
- the document's rules, made alongside the document in the current cicada state
- the "default" rules, rules a document may override
Limitations
Because the documents are mirrored to many recipients, there are limits to what can be enforced. For example, reading messages not encrypted to you can be bypassed with collusion. Or, publishing votes meant to be private. An evaluator might refuse to carry out the selected action.
Role Permissions
For example, the scope of the curator
role is to apply or remove decal tags. They can
have broad allow
permission on that action. However, their role doesn't necessarily give
them permission to admit/reject people from the group (a separate action
).
Syntax
These documents can be defined at the group or server level, for example if the carrier of
the venue decides to allow
, forbid
, require
, or no preference
a particular attribute.
Things like rego/OPA, or cedar, or policykit were considered for syntaxes defining rules.
Permissions should also be somewhat similar to NFSv4, e.g.: list, administer, insert/create, delete, edit, append, replace, read, lock/unlock, change ownership, attribute write/read,
Karma-based rules
Rules can also be based off Karma. Karma is group-specific, though your group may add
in a rule that converts another group's karma for evaluation in specific circumstances (for
example, weighting another group's spammer
karma relatively equal to your own).
Say for example you have a rule about candidates for representative, that they have to
have no more than 20
negative "troll" karma points in group from the mods if they wish
to run as a candidate.
Sliding-Window Karma
Karma documents do expire and forgive over time, though your group can define how this
happens. Perhaps a user can more quickly execute a remedy
action by, for example,
issuing a public apology
post renouncing their troll behavior. While they sit around, they
act as a kind of log.
This also means that positive karma slowly expires (e.g. newcomers vs super-entrenched karma folks). It's a sliding window, use it or lose it. To a certain extent, you could design rules that give a torrent-like random forgiveness to a peer (and grant them a chance to try again with something small).
Because some Mores rules can be constructed to require certain kinds of karma, it can be worth it to keep an identity around and seek forgiveness. The bar shouldn't be so high that it takes forever for new/unknown identities to contribute, but it makes sense to have a sandbox period to avoid the damage from sockpuppets.
Karma isn't exactly something you can GDPR away. When a group decides to ban you for bad behavior, they can keep around that negative rating (and pin your identity). You might ask to have the memo removed, but they're within their rights to keep your phish ID penalized until it expires.
Karma as a decreasing balance
Karma is mostly represented either by groups, or by individual users. Users may have a rule among friends that "new contacts may start out with 20 karma points, but I will deduct 1 point per each message they send me, and 5 for low quality interactions. If I want to top-off their karma, I'll do so in their phish-mores document on my site. if they don't have enough karma, don't allow them to mirror a document to me, don't waste energy storing things I don't want."
Scripted Karma Penalties
Karma might also be deducted or added by scripts to detect large numbers of HTTPS links, or invite rate limits, or constant negative voting/brigading.
Similar to how identities are non-global, hashtags in bivouac aren't global either. Meaning
is derived from who curated the tag. Hashtags in bivouac are managed by .decal
documents.
A tagging relationship is expressed in three documents:
- the tag article (held by the curator) explaining more about the tag in a wiki page (and defining how to address the tag curator's and author's inboxes)
- the curators' list of tagged articles (held by the curator) explaining the relationship from the curator's point of view
- the specific document's tag anchor (held by the author of the document) explaining the author's point of view on the relationship.
Hashtag Namespacing
Tags in Bivouac are namespaced to curator roles. They also contain a colon to define the
superclass of tags, for example #wiki:whales@curator@@coolhacker.phish
for
publications about whales, or #karma:trolling@mods@@coolhacker.phish
for users
warned about trolling.
Microformats
You might be familiar with these, they look a little like microformats
(#namespace:key=value
)
Some example tag superclasses:
#admin:appeal
- encrypt to only the admin of the group#mod:spam
- report spam to mods#mod:report
- report to mods, not to article author#wiki:squirrels
- articles about squirrels#react:downvote
- reactions
Censor Lists
Decal tags also include censored topics, where the item in question that members are asked to not mirror is hashed with a salt. This is a cryptographic technique so as to not reveal the address to the referenced document. In that instance, the list of tagged articles is a list of "hash", "salt", "hashmethod", "memo". This is similar to ahmia's list.
In the instance of a censored tag, a user's client should by default not download, mirror,
or statically render the document. For example, if @@coolhackers.phish
does not want
discussion of cheesy broccoli
.
Community-Sourced Tagging
Users may also use decal tags as a form of content warning.
Tags may also be submitted to curators and authors by people who are neither the curator nor the author. Pending or rejected tags may optionally be viewed by other members of a group or audience (if public) so long as the tag proposal is still live on somebody's box and someone wants to view it. This can be viewed as similar to collaborative tagging in Danbooru, an image board software.
Tag Priorities
If users believe an identically named tag is better curated by group X instead of group Y, they could choose to go with X's curation and only use Y's when X hasn't made a decision. In this way wikis function like a Union filesystem, where some folders come from one hard drive, but deep inside them some other folders might come from another hard drive. Your view of tags is based on who you think does the best tag categorization, and you can mute or delegate as appropriate. You might even use virtual decision flows to decide and weight them.
Syzygy is the home of many configuration settings and voiced preferences for things like notifications, feeds, recommendations, search, and delegation.
Notifications
In bivouac, a group may have roles that have certain duties, or are the only ones who can perform a certain action. These users need to be notified to perform the manual decisions in a timely manner. This is done when their editor emails them (no other nodes on the network know their email address).
Perhaps you want to turn on notifications for any time a friend posts. Or mute a noisy discussion.
An important role in bivouac is being someone's Nameserver. You probably should allow emails whenever their records change, so you can quickly confirm with them out of band and update your record.
Feeds
Bivouac feeds are sortable and configurable. For example, a user might choose to use Reddit's sorting algorithm (the wilson score interval), or they might prefer chronological, or something else.
They might also set muted topics or users.
Delegation
Syzygy defines "autopilot" actions one should take if a user does not manually cast their vote for a decision.
You could, for example, delegate climate decisions to your favorite science curator.
Groups may decide that for certain votes this "zombie" voting should not take place. Or they could decide that the vote should decay by some factor (like 1/n'th of a vote).
If delegation was disallowed or failed to happen (because your delegate didn't choose), you'll get notified before your time is up to vote. You could also choose to get notified of what they picked and approve it.
Recommendations
Syzygy hopes to walk a balance you define to show you deviant/dissenting stuff in ways that respect your boundaries. Many of the tools here could be used to create some serious filter bubbles, that's not necessarily all bad, but it's something you should be able to configure. An example would be similar-topic recommendations.
Recommendations are something that all four of you have to opt in to:
- the author of document A
- the author of document B
- the friend who linked both A and B
- you, the person receiving the recommendation
Recomendations can be simple "find a subreddit" style 'people in X are often in Y', matrix multiplication recommendations. Ideally they should focus on content, not on the person doing the search.
Search
Bivouac search is implemented via static site indexes (there are two implementations we know of, one is used by mdbook, elasticlunr).
The search index should be encrypted to the same Crew audience. During a search, bivouac will draw from all the indexes that you're a member of.
If someone's content is pending moderation, the mods might downrank or remove it from the search indexes temporarily.
Discoverability
Syzygy documents define how discoverable you want to be. For example, maybe you don't want to be publicly listed as a member of a group, or publicly listed on a friends' list of petnames. Or maybe whether you want to appear in search.
Authors of documents also define under what conditions their document is placed in the static search index files.
View From Nowhere
When viewing the wiki in the editor, one can have an enriched ability to view the documents from another person's point of view (provided enough of their preference documents and rules are public). Or, they can view the space of all wikis across the wiki-verse from a "view from nowhere", e.g. viewing all things claiming to be the authority on "Idaho" in a serendipitous exploration of content.
Finally, Bivouac, the voting documents. Bivouac votes are represented in PLAINTEXT
POLLS. These do not use advanced cryptographic PhD schemes, anybody who can
decrypt the documents (typically the auditor
role) can read your vote.
Why Vote
Just because you can do something solo (like forking a group), doesn't mean it's all that fun. It's nicer to agree to work on something as a team.
Philosophically, digital stuff can be forked as much as you like (especially in this petname system). Voting as a body of people forces limited options, bringing it back to meatspace where you can only pick some not all, either due to space, money, or volunteer time.
The different ways you can construct the voting options are because plurality is different from a majority. They're also because some decisions you want to unstick and take action (disallowing filibusters), while others you might want to stick (for example, core beliefs of the group or amending a constitution). It's your sandbox.
State Machine
Decisions in bivouac are represented in a turn (or "phase") based state machine. During a phase certain actions might be disallowed. For example, there might be a time period to propose Options. Later, the options would be locked in and it'd be time to vote on options. You may decide that late entries to options are allowed. Or maybe a petition once started must gather enough signatures before a deadline.
Each of these distinct phases goes through a full Cicada sync, for example any machines that need it can get all the submitted options in the first sync of the first phase.
Who Officiates
Bivouac votes only really need to end up at the people running the decision, you don't all have to mirror everybody's vote (you can if you have the ability to witness the votes).
Facilitator
Decisions are run by a facilitator role, that handles unsticking the state machine or moderating the debaters. They approve changes to Options and decide whether the new edit is in the same spirit as the old one that people already voted on.
Who Argues
Debaters may submit "option" documents, paths that voters may choose. Options define short wiki articles and Actions that will result.
When the options are created, debaters may discuss each other's options in "Argument" documents, one per each of the other debaters' proposals.
Facilitators may choose to allow facets of discussion (similar to multiple tables of data) by creating "Criteria" documents, for example allowing comments about budget specifically, and marking arguments that don't fit the table as off topic.
What Kind of Decisions
Decisions are great when they result in actions. Bivouac is kinda like an event bus, the state machine can listen for events and then change things based on what's subscribed to a vote or what action was picked.
You might be picking:
- a representative (even multi-member elections) verified by membership in the new role
- a change to group rules (verified by signing the new document)
- an outside digital action from a plugin (like talking to an API)
- a manual action (performed and then notes taken)
Choice Templates
Bivouac actions are taken using workflow templates called "Choices". These are templates that don't have a specific instantiation with dates/times or specific related language.
For example, a group might have a general "yearly representative election" choice that occurs in March, and a "petition to recall" choice that occurs when 50 signatures happen. Or, the admission of a new moderator might be a choice template :) - some choices might prohibit syzygy delegation or limit its reach.
Choice templates define what the boundaries are for a decision. When a particular instantiation of a choice is started, this is a "decision" document. It has the dates of the particular phases, the crew lists, the Mores ACLs, etc - all pinned into a particular round of evaluation for that decision.
Choice templates detail a delta of days between phases, for example the minimum and maximum amount of times to wait for candidates. Facilitators can work within those ranges.
Decisions
A Choice template is taken to create a specific instance called a Decision.
Where a choice is like a playbook, a decision is an individual run of that playbook.
A user could specify a threshold number of volunteers for the motion to pass, for example.
Decisions detail the exact start and stop days for each phase of action. Users have to act before those periods end or they miss the bus (or perhaps their default delegation is run if configured). The peers then render their sites after those days and pass around results.
Most decisions happen rather sedately (as in meatspace voting). However, some decisions need to happen rapidly (like moderation decisions). For those it makes sense for the mod to be pinged (via webmention) quickly, or for the mod to be contacted via another editor on the same machine, or some other method. Not settled on that.
Voting
When users are ready, they make "Selection" documents (one per user, enforced by a quirk of Cicada). Depending on the kind of election, that could be a direct proposal, or perhaps electing multiple representative users to a role.
Tagging still functions (it does on profiles or groups, too) - and users might base their delegation decisions on whether or not someone's tagged a particular option a certain way.
These are tallied into a summary by auditors
, who can see who voted for what
(bivouac is plaintext and dumb). You can see the example voting algorithms towards the
bottom of the pages.
Actions
Putting it into Action
The results from the auditor role are transmitted to the evaluator
role as defined in the
original decision doc. That could be a virtual role that just points to a key being used to
sign a statement, or perhaps an API being called to swap some property in the digital
realm. Or maybe Ralph the admin gets emailed and needs to do XYZ physical action.
Evaluators then produce a document showing they carried out the action. Decisions
specify how immediate/live a decision is, and whether there's fully automated, manual
approval, or fully manual actions.
Finished
At this point, observers can see the vote tally, and see that the options that won the decision were acted upon. The vote can be kept around, or discarded out of state.
Voting Algorithms
Selections are counted using an algorithm.
Depending on the voting algorithm, that could be first past the post, approval voting, ranked choice voting, threshold, lazy consensus, consent, etc. - a human may be involved in approving the results and hitting a final OK. Auditors release the summary of the votes, without who voted how.
Approval Voting
Approval voting asks users to check which options they're okay with. It's simple to understand, simple to count, and usually gives outcomes you'd expect.
RCV
Ranked Choice Voting votes record via an ordered ranking. They have some desirable properties but it gets complicated fast. Counting them is also hard to explain, as is picking multiple options.
Rated voting
Rated voting asks you to rate candidates. Unlike RCV, options can have the same rating.
Lazy Consensus
Lazy consensus for example is where:
- +1 - I like it and I'll help
- +0 - I like it but I can't help
- -0 - I don't like it, I have no alternative
- -1 - I don't like it and I'll help with this other thing
It's particularly interesting because it records willingness to volunteer for an option.
Zombie Votes
In delegated votes, a user may not delegate any lazy vote other than +0 or -0. That is, they may not "volunteer" a member on autopilot (called a "Zombie"). Similarly, when electing a Representative or a curator, who's liable to have an inbox of duties, they cannot be a Zombie representative. Users can, however, be passthrough zombies, so long as the entity they've passed through has decided they're a volunteer.
They can also be zombies for matters of simply what preference someone wants to display their wiki with (like tag views). These come into play when a user makes a mini list of say, "if all three of these users tag something XYZ, I'll consider it tagged that".
Each choice template needs to take a stance on what happens during non-response. This is related to Warnock's dilemma and tacid acceptance or acquiescence, or passive assent.
Consensus / Unanimous Votes
Consensus (or unanimous) votes work on the following options:
- yes
- yes, with concerns
- stand asside
- block (with reason) - these vetos typically come with conditions and aren't indefinite
- reference a specific group core document or start a choice template document (e.g. could spin off to a threshold vote or turn the election into RCV if you're blocking for too many rounds)
During consensus votes, an issue is introduced and clarified, discussion is opened, ideas explored, proposals formed and amended, tested for agreement, and implementation is worked out. Blocking usually requires specific grounds and usually involves presenting a viable alternative.
Consensus votes are good for things like core principals of a group, where it's okay to stall on and not do a bad thing.
Threshold / "Four Eyes"
A threshold vote requires a minimum number of people to say yes, for example two mods must approve an admission. E.g. a two-man-rule system.
It's the opposite of consensus voting, where very few people are needed to block a decision. You're probably familiar with doer-approver systems and separation of duties.
You can also clarify that a decision must come from aprovers in two different roles (like one from role A and one from role B).
Coordinated "Random"
Where a decision uses sortion (random selection), it can either use truly random (e.g. random to each node), or seeded random (that will be the same on every rendered node). This is useful for example in decisions where you want to split 1/3 of say an inbox to preferably each user, and then on day two open up the overdue tasks to anyone in the flow, because it allows each node to deterministically compute how things will be split between nodes.
Playbook Chaining
Since decisions function like state machines, you can chain playbooks together into flows. You can also define things like circuit breakers or guard conditions.
Moderation flows could include parts that are encrypted only to moderators, or sections in meta-moderation or appeals where a user can see the decision and why, or can see the accusation but not the accuser. It depends how you build your decision flows.
The example on the next page details a meta-moderation playbook where someone can appeal a moderator decision!
Choice flow example:
- report started by victim
- victim notes (permanent - not visible to accused)
- attach evidence (preserves)
- live action (while decision is pending, to limit damage)
- de-rank search (before hide/remove decision by human)
- rate limit accused user's edits
- ignore list
- repeat COC violations immediate
- mod decides visibility
- are we legally prevented from notification
- will this mod decision be public or private
- which COC violation section are we referencing
- mod notes (permanent - not visible to either victim or accused)
- accused appeal (permanent - not visible to victim)
- mod action
- visibility of content (e.g., CSAM, DMCA, revenge porn, drugs, terrorism)
- loss of delegative authority
- loss of role
- reverse punishments
- feedback (from victim + accused)
- unfair result
- lazy mod
- escalation/redress (to parent group)
- victim notes (permanent - not visible to accused)
- action log
- reporter role (not specific user)
- moderator role (not specific moderator)
- accused/impacting (exact user)
- transparency data (e.g. Santa Clara transparency principles)
- number of search results downranked
- number of appeals
- number of complaints, from which countries, etc
- victim view
- starts off with when the report was created
- list of reports
- clarify reports
- view the mod wiki
- check the options that apply
- decide who to report it to
Some parts didn't really fit in the main doc.
Tor Binary
We considered compiling Tor into the binary, but instead it just asks you install the Tor client later. Arti (a rust rewrite of Tor) is pretty damn awesome!
MDNS
.phish
& .petname
were considered for pseudo TLDs.
It would be cool if .petname
was an IETF reserved pseudo-TLD that used the second
portion to define the service (for lookup on, e.g., mDNS).
e.g., alice.bloat.phish
would mean "resolve alice using a bloat compatible program".
Karma Warnings
a potential 9th system, Hanoi (as in the tower of hanoi), could contain warnings about filter bubbles or mod abuse or whatever - but that depends on how the other systems end up being used. It could be a little warning auto-pilot or auto-mod.
Some types of detections probably shouldn't be in the Karma system itself, but should instead be in the Hanoi warning system. For example, constant blocking no votes on a consensus vote could potentially be turned into a ranked choice or approval vote, but maybe it's meant to always stay consensus? Mores might not care about unanimity and groupthink, but maybe you as a group care about diversity of option choices?
Tag Spam
Depending on the decision at hand, some selections/votes/tag submissions shouldn't necessarily count against someone's karma, but usually any sort of arguments or options presented should (e.g. a much more active role was taken in creating an inflammatory action like a whole Option or administering a whole hateful Crew).