aboutsummaryrefslogtreecommitdiffstats
path: root/src/remake
Commit message (Collapse)AuthorAgeFilesLines
* strict: no strict remake of a swarm strict alreadytv3 days2-7/+18
| | | | | | | | | | | | | Review 2, N2: nothing checked that a strict remake's base wasn't strict already. In a strict swarm the registry, the policy and the bans change only as a user who may change them signs; a strict remake committed by a majority of members, each with keys of its own, could drop any of them (unban, remove managers, empty userSigned and the sealed declarations), and the honest minority would follow. A node now takes a strict remake (proposing or voting) only in a swarm not strict yet: turning strict is done once, by a remake; after it, by signatures.
* remake: aborts written as the user who asks; no abort by timetv3 days2-10/+46
| | | | | | | | | | | | | | | | | Review 2, N3: 1150 let any member write an abort decision once a remake had expired a grace period ago, judged by the change's own time, the writer's word. A member could race the coordinator's legitimate commit with an abort dated as it liked; both taken, Automerge shows one, and nodes that acted on the commit split from those that didn't. The two writers of such aborts are operator requests whose endpoints already need write on _continuum/remakes: aborting an expired remake (DELETE /admin/remakes/{id}) and superseding one (POST /admin/remakes?force=supersede). Both now commit as the user who asks (the proposal and its vote with them, for a supersede), which the rules take as one who may write the decision. The clause judging an abort by its time goes, and with it the time the rules carried. An expired remake is still aborted through any member, by an operator.
* strict: a manifest serves one remake, at its basetv3 days2-9/+27
| | | | | | | | | | | | | | Review 2, N1: a strict manifest wasn't bound to its base. Any member could propose an old, legitimately signed one again at the current heads; nodes would verify it and vote, and every value at a signed place changed or added since (a ban, a new user, a rotated key, a changed userSigned or sealed declaration) would be deleted, nothing after the base being left to replay. The manifest now names the epoch and the heads it was made at, and a node takes it (proposing or voting) only for a remake of that epoch with exactly that base. GET /admin/strict-manifest makes it so; continuum-signed strict proposes at those heads already.
* remake: a strict remake makes the registry, policy and bans anewtv3 days1-0/+16
| | | | | | | | | | | | Review 2, N12: a strict remake kept only the values at the signed places its manifest names, and copied what holds them as it was. A member that replaced _continuum/users by a scalar before the turn left the strict epoch without a registry, where any member may do anything. The holders of the registry, `_continuum/access` and the bans are now made anew as maps, with only what the manifest keeps copied into them; and a manifest keeping no user is refused (at proposal, vote and build alike), as a strict swarm without one would trust every member.
* access: a change judged by the policy it was written under, locally tootv3 days1-1/+4
| | | | | | | | | Review 2, N10: the judgement before a change leaves (1140) and a replay's (1141) skipped changes when the document *with* the change had no policy it enforces. A write removing the policy, or setting one the node doesn't know, then left unjudged, while receivers judge it at its dependencies, where the policy was enforced. Both now read the policy at the heads before the change, as receivers do.
* remake: a replay taken back keeps the node its authortv3 days1-1/+72
| | | | | | | | | | | | | Review 2, N4: replay_newest names the node the document's author once, before its first group. Taking a refused group back forks the document at the heads before it, and Automerge's fork has no author; when the refused group was the actor's first change, the next one was committed as seq 1 without the footer naming the node, refused as "it names no node", taken back too, and so on: the whole replay in the quarantine with a misleading reason. The fork now names the node its author again. Test: the first group refused (a capability revoked in the new epoch), the next replayed.
* remake: no --follow-strict-remakes; a strict remake failing says whotv3 days3-12/+44
| | | | | | | | | | | | | | | | | A strict remake takes a majority of members whose --strict-keys take its manifest's signer: no node votes for one without, so --follow-strict-remakes (1173) goes. A node that doesn't vote still switches once the others commit, as with any remake. So that an operator can tell why one fails: a strict remake aborted for want of a majority (the voting period over, or a majority out of reach) says in its reason (GET /admin/remakes/{id}, and the coordinator's log) which members didn't vote, and that a member votes for one only with its manifest signed by a key of its --strict-keys. Each of those logs why itself (`Not voting for a strict remake`). The sim a_strict_remake_too_few_take: only a takes the manifest; the remake aborts, naming b and c.
* remake: turning a running swarm strict, keeping what an operator signedtv3 days6-12/+241
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Until a swarm is strict, the user a change names is its node's word, so any member could have planted registry entries, policy, bans or user-signed values as any user, plain or signed by a key it put there itself; writing the strict policy trusted all of it as it was. A remake of a new kind, `strict`, turns a swarm strict instead: * Its content is a manifest (access::strict): the swarm, the strict policy, and each value kept at the places values are signed, by the SHA-256 of its JSON, signed by an operator (ssh-keygen -Y sign -n continuum-strict). * Every node builds the next epoch as compaction does, keeping at the signed places only the values the manifest names, as they were at the base, and writing its policy (RemakeKind::protocol, the one kind that changes protocol data). Writes after the base reach the new epoch only by replays, judged by the strict policy. * A node votes for one only with its manifest signed by one of --strict-keys, keys given out of the document; without any, for none (logged once, `Not voting for a strict remake`), unless --follow-strict-remakes. A coordinator proposes only what it would vote for (403). Once a majority commits one, every node switches, as with any remake: refusing to switch would only cut a node off. * GET /admin/strict-manifest gives the manifest keeping everything held now, the values for review and the heads they are at; continuum-signed strict shows them, signs once confirmed and proposes at those heads. The sim a_swarm_turning_strict_through_a_remake: a member plants a registry entry as a manager; the operator's manifest leaves it out; a and b, given the key, commit; c, without, follows; the entry is gone and the policy strict everywhere.
* rules: a carried remake record taken from the coordinator its snapshot namestv3 days4-1/+10
| | | | | | | | | | | | | | | | | Review finding 7, second part: a record carried into a new epoch whole (proposal and decision in one change) was taken from any member, for any remake ID. A member could write a forged record, decision included, for a fresh ID in a single change. The snapshot's epoch metadata now names the remake's coordinator, as the quorum built it. The carried-record exception holds only in a later epoch, only for the remake that made it, and only from the coordinator its snapshot names, where there is no record yet. Wire version 43: the snapshot, and so the epoch ID, changes. The review suggested carrying the record inside the snapshot instead. The snapshot can't hold the decision, which names the snapshot's own hash. So the snapshot vouches for who may carry the record instead.
* remake: replays judged before they go intv3 days4-2/+118
| | | | | | | | | | | | | | | A switching or rejoining node replays late writes as fresh changes naming each write's user, and nothing judged them before they left: a replay every node would refuse (a revoked capability, a second envelope at a signed path, readers changed) was refused everywhere, and with it everything the node wrote after it. Under a policy, replay_newest now judges each group it commits as every node will (rules::judge_held, in the new epoch); one they would refuse is taken back (forked at the heads before it, same actor) and its paths quarantined with the reason. replay_newest takes the epoch. Review finding 3 (remake replays).
* remake: replay from the quarantine where the user may writetv3 days1-12/+35
| | | | | | | | | | POST /admin/quarantine/{id}/replay needs write on _continuum, which never covers user data, and replayed every path of the entry as the user who asked: every node refused the user data in it. It now replays only the paths the user may write and keeps the rest in the entry (left), for one who may; 403 if the user may write none. Review finding 3 (quarantine replays).
* swarm: changes taken unjudged, dropped (REFUSALS)tv4 days1-0/+17
| | | | | | | | | A node refusing changes a peer brought tells it which broke a rule; the peer judges them itself, and if its rules refuse them too, drops them with all built on them (its document forked without them, a fresh actor), quarantining its own writes among them. Wire version 42. Auth plan M6 (rejoin on taint).
* remake: replays keep their writerstv4 days4-25/+198
| | | | | | | | A remake's replay writes each value as the user who wrote it, splitting where several users wrote under a path, so replays are judged as the original writes. Auth plan M6 (remakes, 2.4).
* remake: forgetting and releasing name their usertv4 days2-2/+22
| | | | | | | Forget records and released quarantines name the user who made them, so they are judged by its capabilities. Auth plan M6.
* store: keys_at tells no map from an empty onetv4 days3-3/+8
| | | | | | | | registry::exists counted any value at _continuum/users as a registry; keys_at answers None where there is no map, and its users (records, members, forget records, remakes) say what they make of it. Auth plan M1 (fix).
* refuse misplaced authorstv4 days1-0/+9
|
* dashboard: polish remake ringstv5 days1-1/+17
|
* dashboard: remake switch delaytv5 days1-1/+1
|
* dashboard: add epoch switch indicatortv6 days2-7/+33
|
* dashboard: map remake votestv6 days1-0/+37
|
* fixup 700, 701, 702tv8 days1-38/+2
|
* remake: read ops, not diffstv9 days2-6/+6
| | | | This gives bench_replay a speedup of ~8x/64x/280x.
* api: add type caststv9 days1-0/+1
|
* add remake benchmarkstv9 days2-0/+91
|
* remake: download wakes on end instead of tickertv10 days2-6/+15
|
* remake: decouple grace time from node's keepalivetv10 days4-4/+25
|
* document: allow writes during rejointv10 days4-214/+271
|
* LWW everywhere, mostlytv10 days4-23/+340
|
* remake: copy stale view when writes stoptv10 days2-5/+11
| | | | This ensures that stale reads show every write that was answered.
* remake: log expired and missed votestv10 days2-9/+61
|
* api: off clock refuses aborting expired remaketv10 days1-14/+29
|
* remake: introduce follow-the-majority ruletv10 days1-27/+139
|
* document: reject writes during rejointv10 days4-31/+72
|
* use Automerge as Document instead of AutoCommittv11 days9-144/+174
| | | | This allows a lot of operations to drop mut.
* store function accept any documenttv11 days1-6/+10
|
* tests write through document::testing helperstv11 days5-210/+210
|
* remake coordination use document, not automergetv11 days6-46/+41
|
* one function for changed pathstv11 days1-27/+6
|
* remake needs sane clocktv11 days2-1/+22
|
* remake: drop is_reserved; use is_protocoltv11 days1-10/+5
|
* remake: drop parse_metadatatv11 days1-12/+8
|
* replace EpochInfo by EpochRecordtv11 days1-16/+1
|
* remake: move proposal to its own moduletv11 days3-252/+271
|
* move ChangeSet from swarm to documenttv11 days3-3/+3
|
* talk about "transport" unless mycelium is meanttv2026-10-271-3/+3
|
* remake worker wakes up when vote is duetv2026-10-264-2/+42
|
* describe remake test failures in simulationtv2026-10-261-0/+30
|
* make clippy happy againtv2026-10-263-16/+17
|
* add remake tests on the simulatortv2026-10-262-0/+57
|
* add changed_path minimality testtv2026-10-261-0/+69
|