We want to move from group/permission paths of the form /chat/~host/name
to /~/~host/name, merging the ./read and ./write permission paths into a
single permission matching the group path.
(The leading /~ signifies an "unmanaged" group, one used by apps
internally, and not explicitly exposed to the user as a contacts group.)
This upgrade logic does roughly the following, for every chat path, to
accomplish the migration:
1. delete ./read and ./write groups associated with the chat
2. create a new group containing an approximate "uni" of the old groups
3. register the chat + new group with the metadata-store
4. hook the group up to its matching permission set
Note that because existing groups are hooked up through the
permission-group-hook, doing step 1 deletes the associated permissions.
Step 4 then re-establishes that relation for the newly created group.
The logic here scries into the metadata-store, and as such depends on
that having been started prior to this upgrade process.
When permissions change, find out which chats are impacted (on the
assumption that permission paths are group paths), then perform actions
wrt that chat accordingly.
When a chat is interacted with, find out which groups the chat is
associated with, then use those to perform permission checks. If the
check passes for any group, permission is granted.
We may %hear or %read content that was posted some time ago, so we need
to make sure we add it at the appropriate position (wrt timestamp)
rather than just sticking it at the head of the list.
Shortcuts the existing retry timer by having new members send out a poke
when they acknowledge joining the group.
The existing retry logic is left in place to deal with other cases of
subscription failure.
Also fixes an incorrect relevancy check during subscription retries, now
properly preventing duplicate subscriptions.
We were scrying for /gx/path instead of /gx/=link-store=/path.
In the %annotations case, that path wasn't even correct.
Also refactors scries out into a +scry-for helper.
* origin/philip/gall-ack-fix:
gall: give both acks in case of unexpected ack
gall: make 2140e07 ota-able
gall: properly track remote acknowledgments
Signed-off-by: Jared Tobin <jared@tlon.io>
It's hard to say what's the safest thing to do when we get an ack we
weren't expecting due to losing outstanding.agents.state in +load
3-to-4, so this gives both a watch-ack and a poke-ack. This seems most
likely to succeed.
Does not change state type, but clears outstanding.agents.state since
it's full of garbage values. This introduces a possibility that we may
have been in the middle of something, so we handle that in a reasonably
sane way.
outstanding.agents.state is a queue of what sort of message we sent to a
foreign app. We use it so that when the acknowledgment comes back we
know whether to treat it as a watch-ack, poke-ack, or neither. We used
to put this info in the wire, but this gave us a different ames flow,
which meant %leave and %watch didn't get associated (causing #2079).
The error was that when when retrieving the item from the queue, we put
the new 1-item-shorter queue back in outstanding.agents.state at a
different wire than it came from, so the queues never actually got
shorter, and acknowledgments of the wrong sort were commonly produced.
This caused problems mainly in situations where we poke and peer on the
same wire, and possibly when a subscription was cancelled.
Possibly related to #2206 and #2176. I would expect this bug to cause
those issues, but I haven't verified the converse. Also possibly
related to #2153 and #2079.
"Replace" suggests this function either produces an updated set/map when done,
like +snap, or changes all values in-place, like +turn. In truth, it's more
similar to +roll, which does reduction/accumulation.
("Reduce" specifically was chosen because it maintains the mnemonic relation to
the arm name.)