Skip to content

Instantly share code, notes, and snippets.

@tacryt-socryp
Last active May 12, 2020 22:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tacryt-socryp/d04b6ea442a95a84bff734ba0717fd58 to your computer and use it in GitHub Desktop.
Save tacryt-socryp/d04b6ea442a95a84bff734ba0717fd58 to your computer and use it in GitHub Desktop.
|%
+$ resource [=ship =term]
+$ groups (map resource group)
+$ tag-queries (map term (set ship))
+$ group
$: all-members=(set ship)
=tag-queries
=policy
==
::
+$ policy
$: invite-only=?
allow-comets=?
black-list=(set ship)
==
::
:: example tags (can be used differently in different apps...):
:: %pending - denotes that member has been invited but not joined yet
:: %admin - denotes that member can add and remove members
::
+$ action
$% [%add-group =resource ships=(set ship) tag-queries=(unit tag-queries) =policy]
[%add-members =resource ships=(set ship) tags=(set term)]
[%remove-members =resource ships=(set ship)]
[%add-tag =resource =term ships=(set ship)]
[%remove-tag =resource =term ships=(set ship)] :: if set is empty, remove tag. otherwise remove tag from ships
[%change-policy =resource =policy-diff]
[%remove-group =resource]
==
::
+$ policy-diff
$% [%invite-only p=?]
[%allow-comets p=?]
[%black-list-add ships=(set ship)]
[%black-list-remove ships=(set ship)]
[%black-list-clear ~]
==
::
+$ update
$% [%initial =groups]
action
==
--
@ixv
Copy link

ixv commented May 8, 2020

Upon reflection, I don't think invite-only is a good replacement for a whitelist, because you still need to keep track of who got an invite. I don't think keeping track of that in the invite app is a good idea because then you'd basically have to ask invites if someone has permission to a thing, which should not be its role at all. Policy should essentially just define a function that gets called when someone tries to join your group, sending invites is a different layer on top of this.

I would change this to:

+$  policy
  $%  [%black who=(set ship) comets=?]
      [%white who=(set ship)]
  ==

@tacryt-socryp
Copy link
Author

My thought was that the %pending tag would be given to all members who had received an invite but hadn’t accepted it yet. What do you think?

@ixv
Copy link

ixv commented May 8, 2020

Hm, that could work, but it seems a little weird to let tags have semantic meaning in the groups app itself. I can see how it would simplify some things, but it seems like you could potentially get into some weird states if you permit people to manipulate the pending and admin tags in the same way that they can other ones.

This would also blur the lines about what the meaning of a group is. We've discussed moving toward a more "reified" model, where the group represents actual members. But tags are a subset of the main group, so if we have people in a pending state, it messes that up a bit.

Another thing it does is compels you to use invites, which may not always be desirable. I don't think a group based on a whitelist where you don't send invites is such a weird idea, and I think its good to keep these kinds of options open given that we're still exploring the use cases of groups.

None of these are super strong objections, I just feel it has a smell.

@Fang-
Copy link

Fang- commented May 12, 2020

This gist came up during landscape meeting today. I want to give my thoughts, some of which I shared during the meeting already.

I think its good to keep these kinds of options open given that we're still exploring the use cases of groups.

Agreed, both on the specific case and the broader sentiment. There's a lot of cool things we could theoretically do with groups, that's (currently) impossibly hard to support because the implementation is too restrictive. We're refactoring now. We're probably (hopefully) not going to refactor for at least another year. So this stuff needs to be extensible/flexible. We can always tie things down over time.

on tags

If we want apps to use their own tags, these should be namespaced by app. If we want apps to share tags, these should be fully standardized.
I think the former is pretty righteous. Helper libs (that you give access to the bowl) can make the namespacing here completely transparent, which is nice. Don't ever read another app's tags.

The data structure needs some more thinking. We might want to do by-ship lookups, and we want to give as strong a guarantee as possible that no weirdness like "non-member still tagged" happens. Wondering if we can do a "reverse lookup" data structure with helper core... but maybe vigilance during implementation is sufficient.

Regardless of the above, tags definitely aren't the place for "invited but not accepted" information. Group membership should be double opt-in: you need to be invited (either explicitly, or implicitly through policy config), and you need to actually accept joining the group.
The current implementation does on-invite membership. This weakens the definition of what a "group member" is, and makes it harder for group-member-based logic to operate correctly, especially in p2p contexts.

on policies

A $: for policy seems too rigid to me. Forces the group-store into making too many early assumptions, and causes situations where parts of the config go unused. For example, if you're invite-only, you don't need any other config: it becomes simply about managing the whitelist.

I propose a $% approach, which group-store can handle internally, and thus can be more easily extended. @ixv's proposal gets most of the way there, I'm offering something slightly richer.

+$  group
  $:  members=(set ship)
      =tag-queries
      =policy
  ==
::
+$  policy
  $%  [%invite pending=(set ship)]
      [%open ranks=(set rank) banned=(set ship)]
  ==

(Remember that rank is the "ship type" type. I intentionally avoid "blacklist"/"whitelist" terminology, I find the above slightly easier and more semantically informative.)

You'd just ?- on the policy whenever it's relevant: on-invite, on-join, on-kick, maybe on-leave. Adding additional cases, like "open but password-protected" become trivial to add. If we find that nearly everything except %invite wants a blacklist, that's fine, we don't need to do anything about it, but have a couple options open in case we want to anyway. (using ?+, wrapping $%, etc.)

idk who gets notifications on gists, so cc @loganallenc, @ixv, @liam-fitzgerald

@Fang-
Copy link

Fang- commented May 12, 2020

Actually, wait. Maybe this is a dumb question, I'm two minutes away from falling asleep, but if tags are namespaced by app, why don't they live in the apps themselves? Nobody else will be able to do anything useful with them...

@tacryt-socryp
Copy link
Author

tacryt-socryp commented May 12, 2020

To be succinct, I disagree entirely about tags and agree completely about policies.

They aren’t necessarily namespaced by app. They could be reused across apps if desired. Just a scry away!

@Fang-
Copy link

Fang- commented May 12, 2020

They aren’t necessarily namespaced by app. They could be reused across apps if desired.

Can you explain how you imagine solving for 1) apps knowing about each other's assumed tag definitions and 2) tag re-use across apps?

Also, to answer my own question:

why don't they live in the apps themselves? Nobody else will be able to do anything useful with them...

Because we may still want to display these tags in group listings etc.

@tacryt-socryp
Copy link
Author

I view tag re-use as a non-issue. If apps want to make use of the same tags to provide similar semantics, let them. If they want unique app-namespaced tags with custom app-specific semantics, let them. If we end up letting users generate their own tags and assign them custom semantics within certain apps, that works too. I don’t see any downsides or added complexity from this.

@liam-fitzgerald
Copy link

We should probably standardise on a set of tags for each cross-app problem domain that we are trying to solve. The big motivator for tags right now is permissions and we should absolutely standardise a set of tags so we can handle permissions consistently across apps. If an app wants to use a tag that is not standardised, then it should be free to do so, but as soon as we want to use this tag across apps we should think properly about the issue that it solving and standardise the tag for all apps. We already have far too many dependencies between apps, we don't want to introduce more. Non-standardised tags should always be namespaced, and should be effectively opaque to the apps that don't use them.

cc: @loganallenc @Fang- @ixv

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment