aboutsummaryrefslogtreecommitdiffstats
path: root/src/remake/api.rs
Commit message (Collapse)AuthorAgeFilesLines
* remake: replayWindow and archiveRetention in an octet-stream import's querytv2 days1-2/+50
| | | | | | | An import uploaded as `application/octet-stream` takes `rules`, `baseHeads`, `settle` and `switchDelay` in the query, but not the retentions: for those the document had to go base64-encoded in the JSON form. Now `replayWindow` and `archiveRetention` go in the query too, as JSON like the rules (`{"epochs":1,"age":"7d"}`, as in the body).
* roots: an epoch's root pinned, and named in every handshaketv3 days1-1/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Review 2, N7, the care it raised: a joining node's empty document took as the first epoch's root whatever dependency-less change came first, from whichever peer it joined through; the first epoch's ID is all zeros, so nothing pinned it. A remake's epoch has its ID, the snapshot change's hash, which the rules hold its root to. * Every node names its epoch's root in HELLO and HELLO_REPLY (the epoch's ID for a remake's, its genesis change for the first; wire version 45). A node whose document starts from another root of the same epoch refuses the handshake, logging it: another history under the swarm's ID, a forged root or a genesis started again. * A joining node with an empty document takes as its root only the one it was given (--genesis-root, new), else the one its peers name, and none while they name different ones (access::screen::RootPin, kept in Screening across documents): one peer hands it another root only if it is all the joiner hears, or never, with --genesis-root. A root refused is listed with the refused, what builds on it with it. * The genesis node logs the root (`The swarm's root`); GET /admin/epochs shows it (`root`). A genesis started again under a remembered swarm ID used to merge with the nodes of it still running; they now refuse it (another root), and the docs say to join them with seeds instead. The epoch's identity stays as it is (generation 0 all zeros): records and epoch metadata name it so, and every comparison of epochs with them.
* strict: no strict remake of a swarm strict alreadytv3 days1-3/+5
| | | | | | | | | | | | | 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 days1-9/+41
| | | | | | | | | | | | | | | | | 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 days1-3/+12
| | | | | | | | | | | | | | 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: turning a running swarm strict, keeping what an operator signedtv3 days1-0/+68
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* dashboard: remake switch delaytv5 days1-1/+1
|
* remake: decouple grace time from node's keepalivetv10 days1-0/+1
|
* api: off clock refuses aborting expired remaketv10 days1-14/+29
|
* remake coordination use document, not automergetv11 days1-1/+1
|
* remake needs sane clocktv11 days1-1/+18
|
* remake: move proposal to its own moduletv11 days1-251/+5
|
* describe remake test failures in simulationtv2026-10-261-0/+30
|
* add remake tests on the simulatortv2026-10-261-0/+55
|
* allow aborting remake with unreachable coordiantortv2026-10-261-4/+26
|
* wrap unix timestamps in newtypetv2026-10-261-16/+17
|
* allow humand-friendly durations in APItv2026-10-261-7/+28
|
* remove /admin/compaction endpointtv2026-10-261-22/+3
|
* remove unit suffixes from fieldstv2026-10-261-27/+30
|
* unify API error responsestv2026-10-261-12/+1
|
* add clock moduletv2026-10-251-7/+8
| | | | | The Clock module is the system clock that every unix timestamp new goes through. It comes with an offset that only tests can set.
* bump abort margin & allow aborting active remaketv2026-10-251-38/+174
|
* add force module usable by API and CLItv2026-10-251-40/+7
|
* compact remake fixes base at the committv2026-10-241-17/+29
| | | | | | | Instead of fixing base heads at when proposed, compact fixes them when committing. This shrinks the window where writes can be lost if their author restarts to the switch delay; during replace and import remakes writes can still be lost during the voting period.
* allow superseding expired remakestv2026-10-241-23/+188
|
* add votes registertv2026-10-241-4/+25
|
* put remake content into blobstv2026-10-241-12/+16
|
* introduce majority voting on remakestv2026-10-241-42/+27
|
* allow import remake using the raw documenttv2026-10-241-6/+85
|
* add the import kind of remaketv2026-10-241-2/+8
|
* rename cluster to swarm everywhere!tv2026-10-211-2/+2
|
* make remake switch delay configurabletv2026-10-211-1/+33
|
* add the replace kind of remaketv2026-10-211-1/+11
| | | | | | | | | | | | | | POST /admin/remakes accepts specs with replace kind, e.g.: { "kind": "replace", "baseHeads": ["..."], "spec": { "document": { "accounts": { ... } }, "rules": [ { "from": "users", "to": "accounts" }, { "from": "users/admin", "drop": true }, { "from": "", "to": "" } ] } }
* allow choosing the base in remakestv2026-10-211-4/+53
| | | | | | | | | POST /admin/remakes accepts "baseHeads": ["<hex>", ...], for example the heads of an earlier GET /store?heads=true. Every head must be in the coordinating node's document, otherwise the request gets a 400. Without it, the base is the current heads. This works for any kind.
* turn compaction into a kind of remaketv2026-10-211-2/+55
|
* rename compaction to remaketv2026-10-211-0/+474