Introducing Kits 2.0

Hello @Speckle_Insider group and, again, welcome to the Insider program! Thanks for helping us shape the future of Speckle and of the industry at large.

With this post we want to explain how we are planning to restructure Speckle Kits for 2.0. The main goal of these changes is improving stability and ease of use.

If you’re not familiar with Kits and what they do, here’s a quick overview below. For a longer overview, Dimitrie previously wrote an article about it here. More specific information can be found in the developer documentation here.

Overview: What is a Kit?

Kits are at the heart of how Speckle manages interoperability. They are, in a nutshell, a package consisting of:

  • an object model that defines the structure of data
  • implementations for various AEC authoring applications (ie, conversion routines that make the translations happen)

Whenever a connector is “sending to Speckle”, it needs to convert data (lines, points, beams, doors, etc.) into this intermediate object model. Upon receiving, the opposite conversion happens.

Kits are not tied into the core of Speckle, they are pluggable. Anyone can add/remove them as they wish or develop their own. We’ve seen various h4cK3r$ writing their own kits - if you’re one of them, we’d love to hear your feedback and understand how you’ve been using kits so far!

Kits 1.0

In the current iteration of Speckle we’ve created and have been distributing by default a few kits:

  • CoreGeometry - mostly geometrical objects, and some others.
  • Elements - general purpose BIM elements (currently very Revit centric)
  • Structural - structural specific (curated by Arup)

Whenever a connector (ie. the Rhino connector) wants to send something, let’s say a Rhino line (again, it also applies to the ‘receive’ part), it will call a method in Core that will:

  • using reflection, it will go through each kit it can find on the users’s machine and get all methods capable of converting a Rhino line to Speckle
  • pick the first one and try convert the line
  • if the conversion fails, it’ll move onto the second match; etc.

This approach worked great so far. It nevertheless has a few limitations in the way it’s currently implemented in 1.0:

  • it’s an heuristic approach because the connector doesn’t really know or can’t really choose what Kit to use,
  • there is a high chance of conflicts if, for instance, someone introduces a new kit with the same methods of another kit, the connector could be picking the wrong method,
  • because of the large amount of reflection being used, it’s hard to debug and it’s difficult to report warnings and errors to the end user when something goes wrong.

Most importantly, the conversion operation - handled by Core - was not deterministic. You were not guaranteed to get the right conversion, and, as a developer, the only control mechanism you had was to exclude some kits.

Kits 2.0

Going forward, in 2.0, each Kit will be assumed to be able to handle all element types passing through Speckle. Additionally, when a connector needs to convert an object, it will explicitly pick what Kit to use, if more than one is available.

As a direct consequence, the previously existing kits (Geometry and Elements) will be merged into a single kit - currently named “Objects”. The Objects Kit will consist of:

  • A project containing the schemas (class definitions) (separate nuget)
  • A set of projects containing the conversion routines for host software:
    • ConverterRevit (separate nuget)
    • ConverterDynamo (separate nuget)
    • ConverterRhinoGrasshopper (separate nuget)

The conversion flow in 2.0 is greatly simplified:

  • convert the object using the provided ISpeckleConverter class.
  • if the conversion fails, send an error back.

Discussion Time!

This new approach solves most of the issues of 1.0, but it does introduce a few new challenges, which we hope to discuss with you. The list below is by no means exhaustive, so feel free to add your voice.

Versioning

How will we manage versioning and backwards compatibility?

(A) The simple solution

Never remove, modify or change an existing property from a class. To keep things tidy, there’s several preliminary thoughts:

  • mark old, no longer used properties, as [Deprecated]
  • make sure that they have “sane” default values

(B) The complicated solution

  • If non-additive changes happen in the object model (ie, a property is changed, renamed or removed), the kit’s minor version number should be bumped (ie, from 2.0.0 → 2.1.0).
  • On the end-users’s machine, we always install (and keep) the new minor version alongside all the old minor versions of the same kit (e.g, ~/SpeckleKits/MyKit/[2.0.0], [2.1.0], [2.n.x]).
  • Each object, when converted, will contain the version number of the kit, so that Core can pick up the correct one.

Both have advantages and disadvantages. We’re inclined towards (B) though, as it would provide a more rigorous framework with less room for errors.

Extending An Existing Kit & Swapping Kits

This one packs a few more questions.

Because of the potential for conflicts & confusion (code-wise) in conversions, etc. we’ll go for a single-kit approach: you will be able to use different kits, but they’ll need to function independently.

One of the reasons for the change is also that, while we’ve seen quite a few custom kits being developed by our community, we’ve rarely seen people needing to swap between kits (or sets of kits). The logic here is that, if company Rando develops a RandoKit, they will be using their kit and won’t need the official SpeckleKit active at the same time.

Swapping: Should end-users be able to swap kits from the connectors UI, or should it be an system admin setting?

To start with it will be only be a general/system setting, mainly due to time and dev constraints on our end. We will add an option to swap kits in the connector uis in the beta stage.

Extending: How do I extend an existing kit?

Simple, just fork it and add your extensions/changes. If you feel they’re useful, send a PR and we’ll look into merging upstream.

Kits from scratch?

Totally doable. We’ll provide instructions on how to create a Speckle 2.0 compatible kit.

Licensing

Should we license the core speckle kit under a copyleft license?

This question comes from the fact that we want to share the burden of interoperability and be able to deliver the best & most seamless conversions we can. A copyleft license would encourage that others that extend the existing Objects Kit will share their contributions back - and thus potentially make their way upstream and not get locked into proprietary code bases.

On the other hand, there’s a perceived fear around copyleft licenses and we would definitively like to hear from you what implication that would have on your potential to contribute and collaborate.

Extras: Naming Changes

The image below show ho we are planning to rename the various VS projects.

Conclusion

Like with all changes, some people are going to like them and others won’t, we know it and understand it! Therefore we’d love to hear your thoughts on this, we’ll be following up soon with code samples and alpha versions!

14 Likes

Hi all,

Love this initiative of Speckle inside. I would like to give my opinion on two topics:

On the topic of versioning:
I feel option B feels a lot more professional and future proof, the transition to Speckle 2.0 feels like a great time to make a rigorous change to versioning like this.
If for any reason it turns out option B does not work out, it’s easy enough to go back to version A at that point. The other way around seems harder.

On the topic of swapping of kits:
I feel like the flexibility to switch kits is beneficial to the end-user, but the amount of kits should not be overwhelming. Maybe a set of “standard” kits that are included in Speckle would be beneficial. The user can switch between the standard kits and additional kits can be downloaded and added by the user if they want to.

Regards,

Daan

2 Likes

Great, thanks for taking the time to give us feedback Daan!
On swapping kits, yes, that’s exactly what we had in mind :ok_hand:

Also, here is your badge for being the first to comment: :medal_sports:@Daan

1 Like

That’s totally what we’re going for. Speckle w/o any kits would be… rather disappointing :sweat_smile: This approach does lock the end-user in a potential “only one kit per push” - so objects inside a specific stream version (we’re renaming that to commits, but that’s another post!) can’t have mixed sources - not a big issue in itself.

I feel that another aspect we didn’t describe well yet, in terms of behavior, is un-conversion. This won’t change that much.

The current envisoned flow is:

  • Blobs getting streamed back from the server - as a string. It’s pure text at this stage. Yes, json formatted text, but it’s still text.
  • We deserialize that text into an a specific class (coming from a kit!).
    • If the original class is not present, we fall back on the base speckle object class, and store the props as dynamic props.
    • If the original class is there, no problems - proceed as usual.
  • At this stage we have kit object of a specific type, that comes from a specific kit, which should expose a specific IConverter class for the current host application - no user input needed!

@Daan, agree re versioning. We’ll most likely, in the alpha stage, start without it but add it during the beta stage.
The reason being that it sounds like potentially a lot of work and testing to get right, and we wanna get alpha stage code out to you ASAP :running_man:

2 Likes

All of these changes are super welcome and at the moment, on paper, I can’t disagree with any of the plans. All the compromises seem either well worth the cost or the costs I personally find negligible.

I’ll be looking forward to the code samples since I’m sure at that point myself and many others would be able to chime in more. But this context is a great start!

2 Likes

Hey Guys, exciting times and congratz on making this conversation public!

I want to play a bit more with the current kits before making very thoughtful comments but in the meantime.

Re:Kit
On Option B Who has the responsibility to maintain the older versions? Is the developer providing somewhere all of them? Is speckle maintaining a repository like nuget or pip? Or is the user storing those only locally? I feel that the later would be problematic if the user is relying on an older version.

This might be a feature already. But is speckle handling nested types? What about if those are coming form different kits?

Re:Licence
People will ask can I do my own Kit without sharing it at all? And if the answer is yes but you should create all the base types yourself, then making it copyLeft wouldn’t be so scary. But the point is to make people share, so not sure if this is helping, but it is definitely not hurting. You would need to offer a very compelling reason to make people share. Not sure what that might be…

3 Likes

I agree with @Stam re. licencing. People should be able to roll their own kits. The base for that should be licensed permissively. Kits developed by the community and maintainers should be copyleft. If a 3rd party wants to license them, there could be specific licensing agreements (and a potential source of revenue).

4 Likes

Hi there!

Well, regarding kits, I think the new approach sounds reasonable; simplifying the flow and giving greater flexibility at the same time :+1:

Regarding versioning, I’d also go for OPTION B. A proper versioning system will bring many advantages; being able to identify what version of what kit converted an object is a more powerful and flexible option, as opposed to just marking fields as [Deprecated] to guarantee backwards compatibility.

Plus, if the Core is capable of determining the kit version per object/conversion, the end user wouldn’t know the difference between option A or B… As far as they are concerned, it will magically work.

Also agree @Daan’s point, going from B to A would always be easier than the other way around, if things don’t go as planned :sweat_smile:

@Stam and @luis make a valid point in regards to licensing, although I’m no expert in the subject.

2 Likes

On licensing, i’d really like to hear from the likes of @daviddekoning, @stevedowning, @pieter and @MdeLeur what they expect the reaction from the companies behind would be like.

Copyleft-ing the interoperability parts (object models & conversion implementation) sounds good to us, but I’m quite worried about the perceived implications at higher levels (rather than the actual ones, which are, in reality, quite mild).

Core - the base for creating your own kit - could be be non-copyleft, as @Luis suggests (super nice reasoning btw); so you can make your own from scratch and not be bound in any way. But if you build on the blood and sweat (looking at Revit here!) that went in the “default” ones, you could be, as @Stam says, politely encouraged to share back :slight_smile:

3 Likes

There is quite a lot to digest in this thread! I’ll reply to the license discussion now and will jump in on the other topics soon.

The choice of license depends on the our goal. Is it to encourage contributions or to prevent anyone from directly monetizing Speckle without contributing to the community?

With regards to encouraging community contributions, there are three groups of users (thinking in terms of end-user groups, i.e. design firms): those who use Speckle without making any changes, those who already contribute changes to the project and those who make changes without sharing them back. For the first group, the license doesn’t matter.

For the second group, changing the license to AGPL will not increase the amount of code they contribute, and will also (at the minimum), mean that they need to ask their laywers to confirm that some internal Speckle-adjacent code is not affected. There would have to be a very strong server plugin architecture (which I know is in the works anyhow) so that firms can create integrations to their systems without triggering the AGPL clause about changing the core product.

As well, these same firms may have some code that does not make sense to share (company-specific downstream patches…). Under the AGPL, if they allowed other design collaborators to share access to their server, they would be required to share their source code (clause 13).

(As an aside, the linked article is somewhat naive about how clear issues are once layers sink their teeth in (sigh). Until there are clear precedents on how courts interpret the meaning of ‘Modified Source Version’, this will likely continue to raise red flags with legal teams, regardless of the original intention of the license writers.)

For the third group, who do not contribute changes back to the project, changing to the AGPL just makes it more likely that they will stick with Speckle 1.0 and gradually or suddenly leave the community.

In short, moving to the AGPL will not drive new contributions and may dissuade people from joining the community at all.

I had a quick look for suggestions on how to encourage contributions to OS projects (weareopen.coop, netdata.cloud, sudarmuthu.com ) and none of them cite the use of a particular license to drive contributions.

On the other hand, if the goal is to prevent anyone from monetizing Speckle directly (e.g. selling Speckle servers as a service, bundling a client) without sharing back to the community, then, yes, the AGPL could be effective–if the community has the resources to take them to court!

Given all this, our preference is to stick with the MIT license.

2 Likes

Hi @daviddekoning! The copyleft question on licensing was specifically targeting the kits, not speckle in general. The server, core, etc. will stay non-copyleft (ie, permissive open source). @luis’s reasoning was I think the clearest here:

  • you can use Core to roll your own kit from scratch
  • you can build on top of the existing kits (baptised as Objects by @teocomi now), but then you’d need to share back.

The intention being that - hey, we’ve sweated over these conversion routines, if you improve them or add them - everybody should benefit!

Intentions aside, I think the perception around the license is as important as itself, and your point is totally valid. End goal is to germinate an ecosystem, so if copylefting kits has the potential to trigger lawyerly adventures and other tribulations - we’ll skip it.

1 Like

Hi all,

Just had a quick read through and it’s indeed quite a lot to digest.

@dimitrie, re licensing, my first reaction is that copylefting the Core Kit makes total sense. (Small disclaimer though, I’m no lawyer and am not completely aware of all the consequences this has)

As long as you make sure your not limiting third parties to also develop their own kits and plugins from scratch under their own license, I believe that this should not withhold companies from using and contributing to the Speckle community. (And hopefully a lot of them will!)

Will definitively have a deeper look into this and the other topics as well

1 Like

@teocomi @dimitrie Is there an implicit assumption that all the kits are .Net code?

Are you planning to have an object model definition which is in a language neutral format ? XSD, JSONschema, Express (god forbid). ProtoBuf could be very nice.

Otherwise I fear the Python client (and any non .Net client) would forever be second class citizens.

The other aspect of licencing to consider may be around redistributables.
i.e If the kit contains any libraries by the vendor of the software being converted to/from, we may need to ensure that the developers are allowed to redistribute those libraries.

Hey Steve,

Thanks for your comment. Yes, the current implementation of Kits and Core 2.0 is in .NET (more specifically .NET Standard 2.0, so that it’ll be possible to reference them from .NET Framework 4.6.1 and above and .NET Core 2.0 and above).

We have started considering an object model definition in a language neutral format, but that will come after our alpha release. At the moment the main focus is reaching feature parity with 1.0, and getting out the new connectors and server.
We have also started discussing internally the python client and SDK, but just preliminarily!

Re licensing, we are leaning towards keeping Core and Kits as MIT because of distribution limitations a copyleft license would imply.

Hi, just to add my experience about copyleft licenses.
Just to make it clear on beforehand: I am not against the principles of copyleft. I have contributed to open source (GPL) code bases in the past, but recently we have gained some experience with some of the questions around these licenses and I think it is good that I share some of that experience.

We have recently been looking supported by legal advisors and two legal university professors at copyleft licenses and I must really warn against them if you want to base anything commercial (read: proprietary or part proprietary) on it or tie anything in this domain to it (like servers/platforms like ours). What I understand of it is that the GPL is more ‘problematic’ than the LGPL. Apache licenses are a lot better to use commercially (but are not copyleft) or MIT (but MIT does not protect anybody e.g. in case of liability which might also be a commercial problem).
What I understand is that the first ‘problem’ is that copyleft licenses are largely untested in court (and in what court/country should they be tested?) which means that nobody really has final answers because most of them contain textual riddles which would need to be tested in court to gain final answers (jurisprudence). Until this jurisprudence of specific cases exist each of these cases is a (commercial) risk.
The second ‘problem’ is that anybody can sue anybody so you cannot do what you usually do in commercial arrangements: make agreements between two (or more) specific parties. So there is no real way to control the above mentioned risks. This also implies a commercial risk.
The third ‘problem’ is that most of the copyleft licenses contain wordings from an age where everything was simple and clear; mostly around use of libraries related to operating systems. Now we have things like open source plugins running on proprietary systems (e.g. Rhino) or open source plugins running closed models (e.g. a Grasshopper model) running on proprietary system (e.g. Packhunt.io) containing proprietary components (RhinoInside/Rhino Compute) communicating over internal APIs. What is a library? What is the operating system? Are Grasshopper models data? Or can they be seen as ‘code’/applications? If Grasshopper models are based on open source plugins, should these models be open sourced? When are you distributing? Or conveying?

The final advice we received is to stay away from copyleft which I find a real pity as it would be great if somehow open source and proprietary systems could live together. One route to a solution is to dual-license with a contributors agreement who transfer their copyright to both a copyleft license for a completely open ‘community’ edition and a commercial license which is less risky to commercial use.

I hope this helps.

2 Likes

Breaking changes in kits is something we are dealing with in the GSA converter currently. As such I would be in favour of the ‘B’ option.

I can imagine that users might be jumping between different projects / scripts. It would be good if there was some kind of configuration component / object / file that could accompany scripts (akin to a packages.json or .csproj file) so that I could ensure I am always working with the same kit version.

2 Likes

Hi folks,

In this reply, I’ll be looking at the following questions raised by the original post:

  • Should Speckle clients support multiple kits at once?
  • When sending, how should the kit be selected?
  • Should the CoreGeometry and Elements kits be merged?
  • When receiving, how should kits be selected?

Kit Selection

I agree that the current method of somewhat randomly choosing a kit to convert Native Objects (NO) into SpeckleObjects (SO) needs to be made deterministic.

My understanding of the proposal is that by limiting each user to selecting a single active SpeckleKit at a time (system-wide!), we can ensure explicit converter selection.

There are situations alreay where explicit conversion happens, namely in the Schema Building Component in Grasshopper. No changes are required to this use case to get deterministic conversion.

To phase this as a question: when sending a group of objects (e.g. from Rhino or Revit), should SpeckleKits be chosen on a system-wide basis, a per-stream basis, or a per-object basis?

Selecting a single Kit on a system-wide basis will lead to a very frustrating user experience. People who are using different kits on different projects, or who are using multiple kits on a single project will spend a lot of time going into their system-wide settings and changing their active kit. As Hugh mentioned above, it would be great to avoid human error by locking the kit seletion in on a project or file basis.

Selecting a Kit on a per-object basis will also give a terrible user experience, because, well, selecting the kit for every single object is a lot of work… (that’s a lot of pop ups!) I only mention this option so that we can dismiss it.

So it seems to makes sense to select a Kit on a per-stream basis. I suggest that when a stream is created, the user be asked to select a primary Kit for conversions, and also specify if they want to also use CoreGeometry to convert elements that the primary kit cannot convert. The UI might look something like this:

image

This gives the following advantages:

  1. The CoreGeometry and Elements kit do not need to be merged. Basing new kits on the CoreGeometry objects is Speckle’s interoperability secret sauce, and tightly coupling CoreGeometry and Elements is not ideal. (see below)
  2. This gives any kit the ability to “merge” with CoreGeometry, instead of just the Elements kit.
  3. Once a stream has been set up, the user does not need to remember what Kit was chosen.
  4. Default kits can still be chosen by the client or set on a system-wide basis, so that new users don’t have to learn about it to get started.
  5. Different kits can be chosen for different projects, or different steps of the design process. (e.g. a façade designer might want to use the Elements kit to send some objects to the architect, and the Strutural kit to send them to the strutural engineer).

Merging CoreGeometry and Elements

Picking up the first point, the next question is: “Should the CoreGeometry and Elements” kits be merged?

Keeping the kits separate will help the Speckle ecosystem stay away from slow, IFC-like discussions about what the Kit should be. CoreGeometry provides a common vocabulary to specify geometry for the whole Speckle ecosystem, and keeping it purely focused on geometry encourages a federated, flexible approach to object model definitions.

We might rename the existing Kits as follows:

  • CoreGeometryGeometry
  • ElementsBIM
  • StructuralStructuralAnalysis

Some new kits we might see developed:

  • Geotechnical
  • LinearInfrastructure
  • Facade
  • EnergyModel

For the sake of easy coordination, having all the geometric objects in each kit inherit from the CoreGeometry classes makes it easy to create a federated model for coordination, issue tracking and clash detection, while giving freedom to smaller groups to define and refine their object models.

Choosing a kit when receiving

If we follow the suggestions above regarding sending streams, we will have two types of stream to deal with on reception:

  1. Streams where all the objects are from a given kit or CoreGeometry
  2. Streams that have been created by a script (GH, Dynamo, python, etc…) where there is no guarantee regarding the number of Kits used.

A simple and robust way to deal with all this is to expand the type definition of SpeckleObjects to specify the Kit name and version for each type. For example, a column in Speckle 1.0 has the following type:

type: 'Mesh/Column'

in Speckle 2.0, this could be:

type: CoreGeometry(1.0.0):Mesh/Elements(1.0.0):Column

By specifying this information on a per-object basis, we acheive a deterministic converter selection, and maintain the benefits of specifying a chain of types for a given object. In fact, this gives clients the option of either looking into the type themselves and picking a kit, or just passing the objects to SpeckleCore. Either option will give a deterministic conversion.

As an added bonus, clients won’t need to load kits unless they actually need them for a particular object, so bugs in one kit (cough, cough, SpeckleStructural) won’t crash clients that never use them :).

(As an aside, though we could in theory have long type chains, I suspect that two types–a primary type, and a CoreGeometry type–will be enough for almost all use cases. I would love to hear what others think.)

Summary

To summarize all this, here are the 4 questions I listed at the top, with our suggestions:

  • Should Speckle clients support multiple kits at once? Yes. Allow users to select a Kit when creating a stream.
  • When sending, how should the kit be selected? On a per-stream basis, with optional fallback to Core Geometry.
  • Should the CoreGeometry and Elements kits be merged? No
  • When receiving, how should kits be selected? Specify the Kit, version and object name in each object, and select a converter on that basis.

I have framed my comments around specific questions in the hope that it will make it easier for everyone to engage with the specific topics. Please share your opinions!!

3 Likes

Hey @daviddekoning, thanks a lot for the detailed response and feedback, it’s very much appreciated.

In regards to your suggestion of not merging the existing kits, and keeping CoreGeometry, Elements, Structural etc independent we see some major issues, especially if we want to make the conversion mechanism deterministic:

  • users would not be able to send or receive streams with objects from multiple kits, eg from both the “BIM/Elements” and “Structural” kit.
  • while these kits are theoretically complementing each other, there would be no way for us of guaranteeing there are no overlaps or conflicts in the schema (and we have seen some of these issues in the current implementation).
  • it would add a lot of friction to the end user as they would need to know, before sending any objects, in exactly which kit they are defined. This would not be the case if the existing kits were merged into one.
  • users would also need to switch kits much more often than if a single kit included all AEC disciplines

With Kits 2.0 we’re not only proposing a new way of structuring the various object models, but also a new way of using the kits. Kits will no longer complement each other, but contrast each other, so that users will only need to switch in between them in rare occasions (eg an Arup engineer collaborating with Grimshaw on a project where Grimshaw has developed and uses their own kit).
Ideally, we want to almost hide the concept of kits from the end users, leaving it only to speckle hackers/developers and systems admins.