 Hey, Patrick. Good morning. Is the, hmm, hi, Innocence Autopilot. I'm not sure if it's a bot or, well, anyway. Oh, we have Nayan. Hi, Nayan. Hi. Good to have you. Let's see if we can get more people to join us. Can start in a short moment. It is AI, OK. It's interesting. I remember, actually, I think the first time the Innocence Autopilot had gone connected, it was actually a person. And I guess then it turned out. It was innocent. It was innocent grades. It actually says that it's his bot. Yeah, yeah, right. Like, I'm an assistant helping innocent grades taking notes. Ah, yeah. Ah, OK. See, it's like personal bot. Yeah. But I don't think it's actually for personal reasons. I don't know. Otherwise, who knows? Maybe I'm just too untrustful to these AI bots. Maybe it's an actual genuine person just saving their time. Anyway, if you hear us, Innocence Autopilot, we'll be happy if you sometimes join us in person if this word skits you through the transcript. Anyway, let's get started. So I'll share my screen. Close up all the unimportant windows I have. I think that's good. All right, so welcome to July 20, 2023. RZVCX Community Call. Entitrust policy of Harper Ledger is in effect. And yeah, let's get started. So I don't think there's any introductions today. It's not a new prequel. Obligatory kind of, well, I added this. Inspired by other meetings I attended recently. I added this kind of point to make sure that if you guys have anything on mind, you would like to add to agenda. You can point it out now so we can adjust it. I added some stuff just a couple of minutes ago to the end meeting discussions. But just to keep in mind, they're already there. So nothing new to that. So I guess that would be it. Nevertheless, if someone would have an idea or thought you would like to put out there, feel free anytime during the meeting. Nevertheless, yesterday we had a presentation on Aries' boardroom call. So the recording is available there. You would like to see. We did a presentation of Aries' VCX. There will be uploaded diagram we created. And I also put it here as kind of status overview of what we did, what we are doing, what we are planning to do. Next up, I kept this item here in case that kind of optional updates. So you see that we have only nine here. So if you would like to give an update, you can. Would you like to say a few words about what's your latest progressives? So yesterday in the Slack chat, I was recommended to look into feature flags and to basically change the implementation of the database back in from any database to selecting one particular database at compile time rather than selecting the database at run time. So I looked into feature flags. And I think I've implemented that on the server now. I've sent a link in chat. So basically what I do is I have some feature flag, I mean feature flag based code. When you give a feature flag saying, OK, we're going to activate MySQL, then it's going to only load the code that's required to give a MySQL pool and so on. So for Postgres, it'll do Postgres. By default, I have activated MySQL. And if someone says they want Postgres, they can activate Postgres. If someone says they want any pool, that is run time selected database, then they can do that also. Yeah, so that's where I'm right now since yesterday. Right. Cool. And we had lots of discussion about the overall architecture and the protocols and stuff like that, right? Yes. What's your feeling of like, do you feel like you understand the big picture? Like, do you have some shadow areas where you feel like you still need to shed some more light on but it's a little bit mysterious? What's your feel or thought on the overall project scope and like the work ahead and things like that? Right. I think I'm getting a hang of it right now, especially on one side working on the server. And then we had the discussion on Tuesday. You explained through the connection protocol and the whole flow of the mediator with the RFCs. So I do have some understanding of it right now. Of course, the interaction with Aries VCX code, that for me right now is a blur, but I guess over time when I actually look into the code, then it'll make more sense. So right now the Aries VCX paths, the methods that I'll be calling there, that's foreign to me. Yes. Right. When I dive into the code, maybe it'll make more sense. Like I'll have to back and forth with you all to understand how Aries VCX works and stuff. I did have a session. So last Friday, I had a session with Miroslav about the message create, I think. Yes. I think that was true. Yeah, yeah, it was bugged on, I think. Yes, yes. Sorry. So we had a session about the message create and we discussed in Lens about it. And yes, some parts were quite complex, but yeah, I mean, I'm getting a feel for it now. With time, I guess looking into the concepts more and reading about it, I think it'll make more sense. Yeah. Sounds good. That's great. Actually, now, as you mentioned, like Aries VCX is kind of a blur for us. Brings me the, reminds me of the idea from George Mohrn about creating like Alice Tabor CLI demo. And we just got freshly merged PR about like a kind of simple message relate, essentially like extremely simplistic maybe if we can even call it that way. It kind of serves like ultimately kind of serves the purpose, but it's like a few lines of code essentially. But this will make it much simpler to create some sort of kind of showcase of how Aries VCX can be consumed. So I think we can finally now like address this and actually create some like simple Alice Tabor demo and that I guess the earlier we do it and perhaps it can actually be helpful for you as well. I had of starting the integration of Aries VCX with the mediator code. All right. Yes, I'm looking, yeah. Thank you for update. We don't have Swapnail, so neither George. So I'll skip over this one. I'm not really in position right now to cover it, but I just know that there's a PR for a while. And it's been progressing somewhat. There have been some comments. So we'll see how this goes. All right. So back to the more mundane part of the meeting. So we had a really 0.57 recently. So yesterday, you had to adjust this change log is auto-generated, but it can be a bit pretty fight and structured. So we'll do that. There's lots of stuff went into that because we didn't have release for, it was at least a month, maybe more. So I'll kind of make this nicer and it'll be easier to understand what all the stuff went in here. Then we had the message really merged from George, as mentioned before. And lastly, there was a number of micro or like mini fixes, some refactoring, some testing discrepancies in terms of tails, deer and tails file, variable aims, then removing unused constants and lastly some CI fix. Then in progress, we have a kind of, well, not really in progress right now, we have passed the credits to unknown credit migration. We have PR for it, but it's more of a draft just a reference point for the future. And we pause this, we need to get clear up some things about intentions of unknown credit and the plan just to make sure that our plan and our approach is right. I don't know, George Bogdan, do you want to drop any more words on this topic? Yeah, I don't know. I guess we've been discussing about this at length, but overall, as you outline, it's pretty much about kind of getting a better understanding of what the plans are regarding all the underlying libraries and how to align or even maybe shape them ourselves or help with that. And also align our goals and approach to better fit into that because we haven't really done that so far and it's kind of biting us in the back, so the sooner, the better kind of thing. Yeah. All right, next up, deductions protocol is, well, it's simply in progress still. There's lots of back and forth. I think last week at Mira, he said that I got some test passing, but he's not satisfied with the implementation, so he's reiterating and trying to find better ways before he kind of pushes it out there into ether publicly. So this is still in progress. Next up, I personally have another small PR to clean up some discrepancies about TELs, d.u. slash TELs file variables in issuers code that might be actually breaking change, like breaking change, but without much impact, I believe. And lastly, Bogdan started VDR tools, credits, world migration, like adding the API to the Node.js. Is that, we have a PR for it, but there was some comments. Is it in progress or are we going to plan out? It's not since yesterday, it's not since yesterday. It's just those tests that have intermittent fails. The building ones, they're not related to the TELs. So I added the test for the wrapper or the function exposed through the wrapper and it all seems to work fine. So it can be reviewed and even merged. Should be in order. All right, upcoming work, we have the CLI demo. We want to do the CLI demo. I think if we do it as soon as possible, it can kind of accelerate Nyan for sure with the mediator, there is this integration. The state pattern, I mean, I think I should remove that. That's like all topic. We all know this is happening. We are doing it and did exchange. We are going to do it in other protocols, but I think technically it's still upcoming. Okay, and ATH back to an update. That's actually in progress. I'm going to move this item because Mero is busy with that. He is the first step as a part of implementing the exchange. It found it useful to basically start testing with testing the did exchange implementation against ACAPI and other implementations right away. So the first step to even be able to do that was just update the RGD6 version in the ATH. So I believe this is done and now it's in a stage of like adding the support for did exchange into the ATH back channel, kind of in a parallel with actually implementing the exchange. And yeah, then we have coming to the end meeting discussions and items added from Bogdan. So I'll leave it to you to moderator what you wanted to say about these. Yeah, so since that the migrators for the exposing it through the Node.js was done yesterday started working on kind of getting the connection protocol up to speed with the, let's say the design choices that we've made regarding state machines. So the connection protocol was pretty much the first and only so far to implement the type state pattern. And we further iterated on that to kind of change the states from sending a message to just generating the message and leaving it up to the user to do that. And I believe Mira is basically shaping the did exchange state machine protocol implementation to fit that design. There's George's PR on the holder. It's kind of been staying for a while, but anyway, he started in that fashion as well. And yeah, I kind of wanted to get some hands-on experience with this and kind of see the challenges and all that. And the main thing that I guess represents, I don't know, or poses some problems is what exactly should happen from a consumer's, consumer of the library point of view with the outcome of the state machine or how are they supposed to even process it? So ultimately, regardless of the protocol and state machine, there are pretty much three things that can happen. You get a message, you locate your state machine and you want to process it. So once that processing starts, there are basically three possible outcomes. You either everything works well and you get the state machine to the new state or some things fail, but that doesn't necessarily terminate the protocol. It's just, I know it could be recryable. So you still have your state machine in your old state and that's fine. There are further actions that you can do based on that, but maybe send the problem report or not. I don't know, that's debatable and it's not necessarily the point here. And the third outcome is basically that and some sort of fatal error occurred and the protocol instance should be terminated completely and is not retrieval. So it's basically success, retrieval or like error, but retrieval and error, but fatal. And being thinking about like how to kind of deal with this because this is going to be sort of a universal thing. Now, obviously, for instance, the connection protocol doesn't even have like a failure state that doesn't terminate. There's no fatal error that can technically occur. But I believe this actually became a topic of discussion when George started working on the holder implementation which apparently does have some like failed states where the instance of the protocol is not supposed to be to be retried, so it should be terminated. And nevertheless, it's a matter of how could we perhaps approach that in a more organized and uniform fashion since having all these different outcomes, like if you take a singular transition and consideration, the transition might be successful all the time or it might be successful and successful or retrieval or it might be successful or fatal or it might be all three. And having differences in these results where these return types from the transition can make it especially confusing for consumers of the library, right? Because in the end, if you look at the ecosystem and the other implementations, and that's maybe something that I'll go that I wanna talk about more regarding the second point, but they're more like batteries included or there are more abstractions going on so that consumers are not that concerned with the actual implementations or the functionalities of the protocols and whatnot. Because frankly, they don't even have to be like, people generally just want an agent to work and just do its magic under the hood. Now, obviously having flexibility of changing stuff around to better suit your needs in your use cases is a great thing, but I'm certain that the majority of people just want a working thing. And basically as a consequence of that, when you have all these transitions from all the protocols and all the state machines and they each kind of return a different thing that you have to handle differently because they're different, it kind of makes things convoluted and complex and hard to keep track of and hard to understand. Again, maybe not for us as developers, but we have to kind of consider the people that would be using this as well. So I've been mainly thinking about the uniform approach of kind of a uniform result, if you will, of the state machine of a state machine transition. So regardless of the protocol and state machine and the state, it would basically return an enum with these variants. And there's also the idea of what should you do as a consumer if you get an error in a transition, right? And I wanna think about that a second. I wanna think about that a second because if you get an error in the state machine, especially given the type state pattern that we employ and the fact that it's a consuming operation, you cannot just error out and propagate the error, to the upper levels of the library or the consumer code because the consumer is supposed to do something based on the outcome of the state machine transition. So consider that if you get a successful transition, you might wanna update your state machine and your permanent storage or database or your cache or whatever, but you definitely need to do something based on that. So if you get a success, you need to do some stuff. If you get a retriable error, a retriable outcome, so you get an error, but the outcome is retriable. Now, what we kinda wanna do is return the old state machine as is. But that might also imply that if you have some in-memory cache where you took the state machine out of, you might wanna put it back. So again, you might wanna do something based on that. Additionally, if you have a problem report that comes out of the state machine, you might wanna send that. So it's not just a matter of, okay, I got an error, it's a result, I'm just gonna use the question mark and throw this up or technically down the stack. And then if you, like if the state machine just terminates, you get a fatal error, then again, you need to do some stuff. You might wanna clean up the state machine instance from your permanent storage, from your cache because that's not supposed to exist anymore. There's not that much that you can do with it. You can definitely leave it there if you want, but I assume people would generally just wanna get rid of it. So nevertheless, there's stuff that you need to do in practically every case of this. And what that means is that even if we kind of consider just returning a result with some stuff, I'm not even sure that's, like I tend to believe that's not really the, there's not really the way to go about this. What did you write down? Assumption to remove state machine on failure. What was that? Ah, yeah, machine on my screen. Ah, it was just a personal note. It's just a minor remark, you know. Yeah. Yeah, yeah. Can you please repeat your last sentence? Yeah, so if the transition, like if you encounter a fatal error, you might wanna do something with that, with a different thing than what you would do with a recoverable error, let's say. What do you wanna do with that? It's absolutely up to the consumer, like whether they wanna just remove the state machine completely from all their storages or, I don't know, log some intricate stuff based on what happened, I don't know. But you definitely wanna do something and the odds are that it's gonna be something different than what you would do from, if you encounter the recoverable error. Right. I know, yeah. Do you think that's fair? Yeah, I think it's fair, it makes sense. Yeah, I guess this is pointing towards like the, maybe pointing towards the kind of custom enum, right? Kind of help you solution or implementation for this kind of idea. Right, yeah. I guess that could work. Honestly, it's a bit, we don't have a mirror here. He's kind of more in the bushes, like in active words about this topic right now. So he might have like more opinions than me. This is still like just the discussion level and yeah, it would be, I mean, we're definitely gonna get him, get his opinion on this. It would have been nice indeed if he was here, but I don't think it's that big of a deal right now. Yeah. It makes sense to me as well. It makes sense to me on top of my head, like on top of my head, I can't really tell what are those retribal and what are those fatal errors honestly. Do you have any, like, I know it probably- I'm sure this is being described. If you open the holder pull request, the one that George was working on, there's been discussion there about these things. Um, let me see if- For this one. Yeah, so when the after the offer is received and I guess the request is sent, apparently for the old API, the state machine transition into failed or request sent now. Sorry, there's some comment I can find about this. There's actually, there are some diagrams that you made. Maybe- That was on the top. Yeah. Yeah. So I guess this would be an example of, you know, a fatal error, I assume, because once you transition to the failed state, you're not supposed to do anything like with that state machine anymore. Or at least that was my understanding. Let's see. Now when I'm looking at this, I'm a little confused because this, the diagram I did here, it looks like it's doing like IO in the transition. Yeah, disregard that. That's not important. It's not necessarily about that. This was before we were discussing the IO thing. But- You're preparing the request. Yeah. It's a matter of, yeah, like an example of a, I don't know, final but failed state that can occur. Like we know ahead of time, even if we do this multiple times, we'll never succeed, right? Because it's some like, maybe it's issue with the request itself or something like that. Right, right. So I guess that's the kind of thing. So that would be like a fatal error, right? But then you could have stuff like, I don't know, ledger communication error, where it's just a matter of networking, a networking problem. And that can be by all means, a retryable, right? So- But if we do like, I assume that like only IO, like in those state machine would be, can I assume that it would be only- It's just an example. It's just an example. But- Yeah, but I think it's still important to like, understand like, what could it be actually in practice? So like, I think it wouldn't be, it wouldn't be sending like, response because we are not doing that. I think it also wouldn't be ledger communication. Technically it could be wallet. That's like the kind of thing. Like if you want to make it really, I guess top notch. I wouldn't be- I wouldn't be ledger communication. If I wouldn't- What can be, I mean, that's the, for me that this is the type of IO we will still keep in state machines. And that can technically fail because it's IO, right? Right. So that's, I guess that's not only actually case in my mind where like retryable error could technically be returned because you could not reach your wallet because it's my SQL database or something. But I don't take many other cases because everything else seems to be deterministic. Like you got state, you got some input data, it works or it doesn't work. The only non-deterministic part is the wallet. So that could be like retryable error. Right. So that's again an example of that. So, yeah, it's basically like a matter of kind of having a uniform approach for these. And like the thing with that is that it's, I don't know, it's a nice thing to do. I kind of drafted something, by all means in a very early draft state, but if I could share my screen maybe. Oh, yeah, for sure. I mean, what comes to my mind, sorry, just a random thought is like having the retryable error gives us like option to actually, yeah, gives us option to have IO in state machines. Like if we actually find out in during the implementation of whatever verifier or I don't know, whatever futures actually protocols gonna be, that like, it's gonna be like really a lot more convenient like for the users, if the ledger communication, some sort of DID resolution was actually in the state machine based on the message received, then we technically, yeah. Yeah, that's what I was talking about. Do the IO inside and return retryable error if IO fails. Wait, what? I lost you for a second there. So you were saying that it would be convenient for consumers if we had the ledger interaction within the state machine? Yeah, so I mean- Which implies IO. Yeah, yeah. So I'm just saying that like having the retryable error gives us kind of a backdoor, like an option to put an IO into a state machine if we deem it as in the last- Because if we don't have retryable, then we, if we don't have retryable and we have IO, then any IO error would become like fatal or other way around. If everything is retryable, then even fatal errors are retryable and it's like really stupid bad for consumers, right? So either way you kind of get kind of a bad solution, but with three, three, retryable and non-retryable, you can technically have IO errors and non-IO errors. Exactly, yeah. And there's basically maybe another simpler example, like based on the thread ID, you're supposed to verify that, okay, the message that you got is, you know, on the thread ID of this protocol instance. And if it doesn't match, it's not necessarily, at the end of the world, there's nothing wrong with the state machine, you just got the wrong message and that's their problem, not yours. You can maybe send problem report or whatever, but it's not something that went wrong with the state machine or, I don't know. Nevertheless, so yeah, basically we could have something like this, which, like I said, it's basically has the okay variant, which has the new state, the fail variant that has the old state and maybe a problem report or an error. Let's not nitpick on this. Maybe we could have four variants instead, one that has a problem report and one that has an error and then the aborted or the fatal or whatever variant that basically has. Honestly, I'm not even sure if it has to has something. I'm starting to doubt those failed states as well. Like what are you even supposed to do with those? There's not really that much that you can do, but let's assume that we have some failed states and state machines. So that's what you would get returned here. I'll just drop a note here, you know, because, and that relates to the, you know, the notes in my sublime you were asking about wrote like, it seemed like you had the assumption that when the state machine fails, like you will throw it away. But I think generally that's not true because you own some sort of like book, you know, keeping track of what was happening in the mobile use cases. You often want to have like kind of a list of events and have actual name for it. And you would want to see, like, you know, you fail to share credential or something went wrong, things like that. And on the back end, likewise, like, you know, as an issuer, I want to know if I failed to issue them credentials. I want to keep track of that. So just to know that I think those failed states, my opinion are important. I'm not saying they're not important, but what I'm trying to get at is, are they important in the context of the state machine states or are they important just as some events that you keep track of? Because they're not the same thing. That doesn't necessarily mean that having like, you might as well just get some sort of an error here, right? And that's an error, the fatal error and you know exactly what went wrong. But without needing to, I don't know, update your state machine or delete it or whatever you want to do. Like the bookkeeping doesn't necessarily mean that you have to maintain an instance of that state machine and the failed state necessarily. It can be then confusing because you will have a state machine left in like non-failed state and now someone, whatever, request send. Yeah, which is why I was saying you could basically delete that and just keep track of the, like the event that this whole protocol instance failed, but not necessarily as part of the state machine. Okay, let's maybe... Nevertheless, like I also understand what you're saying and it's not necessarily bad. Like even if you have like a failed state and maybe keep it, I don't know, together with the other states of the state machine and you have some other bookkeeping job that maybe archives old records or something like that, that also seems perfectly fine, honestly. It's not like there would be an issue with that. And maybe, I don't know, in some regards it might even be clearer. I don't know. So that's definitely a matter for debate, but the bottom line that I was trying to get at is that you definitely want to have a distinction between these and these. And regardless of which variant you get, you want to do something with it, right? So if you have a failed state here, that means you still have to update your failed state, you're like your state machine instance in maybe your database or your cache because the next time, otherwise, like you said, the state machine would remain in its old state, like request sent, and then you're not supposed to have it like that, right? I don't know, does that make sense? Sorry, you're not supposed to have it like what? So I was basically trying to get at that, whatever variant you would get, you know, one of these variants that you get out of the state machine, you have to do something with it. You don't just propagate it someplace else, you know, or you don't just propagate the error someplace else. You first need to do something with this, whichever it is. So if it's a success, you update the state machine. If it's a fatal error, again, you need to update the state machine. So you set it to be in a failed state. And if it's like retryable, then you might want to do something with the old state, maybe send the problem report, maybe log the error, maybe do whatever you want to do. Yeah. Right. Yeah, so that's kind of made me think about this. I'm actually thinking that there's like this problem report or error, I'm maybe thinking of flattening this and just having four variants in here. And the reason for that is like, I think it should be our responsibility to generate, I know, standard problem reports for things that we are aware happened. But not necessarily all errors result in a problem report. So that's why I think it might be helpful to have a distinction. Like sometimes you will return the old state and a problem report that the consumer can decide to send or not. Or in other cases, you return the old state machine. So it's still a retryable error, but the error is not really meant to be a problem report. Like if the communication with the wallet fails, that's not a reason to send the problem report to the other party. The other party doesn't have anything to do with it. Yeah, that's right. Right. Yeah, so that would be that. So you can consider maybe four variants here just for the sake of flattening this. I'm wondering if ever with the failed state, which I consider that's supposed to represent the kind of retryable error, right? Yeah, yeah. If you would actually ever send a problem report when you get retryable error kind of error because if it's retryable, that means that some issue must have happened. You know, some issue must have happened like, I think on your end, like typically with the IO as I meant, I feel like we could even, I'm not sure, might be true. Not with the IO. If something happens with the IO, that's not the other party's problem. Yeah, yeah. But I feel like the retryable errors will be 19, I don't know, 100 or if not 199% IO errors. You just can't think of anything else than IO for retryable kind of error. Like I said, the thread ID, that doesn't match. But if it doesn't match, then. They send the wrong message, but that's their problem. But how would, like it can be also your problem. You actually don't know, maybe you just like did a bad job with like matching the correct state machine. And now you are sending problem report to, maybe someone else or like you did that, just you wrote the buggy code on top of this and you matched the wrong state machine based on a message you received. I would try to process the message with the state machine you incorrectly found in your database, let's say. And now it throws like, oh, no matching thread ID and you send a problem report, but it'll be like actually, you know, actually it's just ended up being kind of confusing because there shouldn't be anything. You have to do something with it. I don't know if this is the only case, but I'm certain that there are a lot of instances where you're supposed to kind of send a problem report without necessarily meaning that your protocol is terminated. Like, okay, yeah, your use case is valid, but then it might as well be the other use case where the other party sent the wrong message and you send them a problem report so they can be aware of the problem or final hope. Well, I think once the problem report is sent, like it's, I don't think those, I haven't seen protocol which is kind of like have this kind of recovery kind of stuff in it. Or like, it sounds like, I mean, it sounds great, like very robust, but I don't think that actually in every community right now, there's this kind of, you know, even on the RFC level, typically when the problem report is sent, then you switch state to some sort of failed state and it's kind of the end. I'm looking right now at the credential issuance 1.0. Hold on for these diagrams. And well, actually, you know, in those diagrams, they don't really even like I mentioned the unexpected conditions. Like there's a problems report, like taking a place there, they're mentioned in issue credentials 0036, for example. But if you get a non, they didn't like draw in the diagram, the kind of cases, edge cases, like if you get a nonsense message, you send a problem report, you know? I mean, they said something like, if an issuer might offer a credential for a price that the holder is unwilling to pay, all errors are modeled with the problem report message, easy to anticipate errors, we set the flow. I think I'm still showing my screen in a minute. Okay, let me maybe bring this up here. Issue on sub-bendant. So does that mean that? Okay. Well, fair enough. So we could argue that then there's, like if you get a retrieval error, there's not even a problem report to send. You might want to send a problem report if you get to that completely failed state. Yeah, I think so because that doesn't make sense. That implies you receive bad input, right? And you want to tell them, oh, like, hey, you send me like, fair enough. Fair enough. Yeah, it does make sense. Okay. So I guess then in that case, it would be something like, I don't know, maybe this error and then maybe various VCX error and then maybe an option problem report. And this is a generic here because the connection protocol uses a different problem report. And you might not necessarily generate the problem report out of this. So I guess having it as an option is a good idea. Okay, so there's that. Yeah, that's basically the overall idea of this. And I think that would make it, it wouldn't come with less cognitive complexity because in all these cases, like these things can, these are the things that can happen out of the state machine, of any state machine, of any protocol, right? So whatever you're doing or whatever protocol you're in or state machine you're in or whatever message you're processing, these are pretty much the outcomes that you're going to be facing. And I think it makes it easier for consumers, especially to kind of reason with what they need to do based on the outcome, as well as kind of making them do something with the outcome and not just getting an error and, okay, I'm just going to question mark that and this is it. Yeah, yeah, that sounds good. Now let's sync up with Meron and see what kind of, what he thinks about this, what kind of, I know I remember he also has some sort of state machine result kind of structure, you know? I don't remember exactly what it looks like so we can kind of compare it and discuss further. Yeah, and maybe we can discuss a bit about the other topic and essentially I've been thinking since the discussion yesterday about the fact that we are kind of making a library whereas the other people are making a framework and when you think about it, I think there might be a fairly good reason why everybody else is making a framework and not a library and I think it's because essentially there are quite a limited amount of let's call them moving parts in all these, in all these areas, ecosystem ideas. Like, okay, there are the protocol specifications so the protocols are kind of supposed to behave like whatever language you implement them, there's practically supposed to behave the way they are described there. Like the moving parts would ultimately be maybe the ledger, the wallet, the storage for the state machines and whatever mechanism you use to receive and send a message. But apart from that, I don't really think there are other things that are, let's say, that there would even be a reason to have to deal with other things apart from that. Maybe there's more, but nevertheless, I think there are ultimately a limited amount of things. So, because I was thinking of, okay, this would be a uniform approach and would be of a less cognitive effort to consumers. But ultimately, what if we could even make this less of a cognitive effort for users? I think this is definitely something, I think this was also Miro's concern and why he's coming back and forth, he's not satisfied because I feel like if he finds it too complicated, he invented some sort of small, helpful layer on top of the state machine to make it easier for the consumers. But then at the same time, he didn't like the kind of inconsistency in the approach, like now there's something new, something extra on top of that. It's just asymmetry. It's not beautiful. And what you're saying, with the library is a framework, I think you're right, maybe we'll eventually make a full circle because we came from a framework where we did like, it was like super con me, the Livy CX is supposed to be the original Livy CX, and it handled agency for you. It like, coupled the connection protocol with the agents, you really didn't have to like think about somehow integrating them. You didn't have to deal with like fetching the messages and stuff like that. But then at the end of the day, we actually wanted to have that like kind of extra control. So we had to start like taking doubts, start downloading the messages ourselves and then putting it manually to connection, to connection state machines, stuff like that. And that was desirable because on the upper layers, we kind of needed that extra control for reasons TM. But I honestly don't think that's what makes the framework. Honestly, right now the difference between like there's actually a kind of small and well-defined difference between us as a library and ARIZ VCX as a framework. Particularly, these I don't know, these are called state machines that consumers would have to deal with in all these possible states and all these possible results and whatever. Because ultimately like a framework, like a library used in whatever way you want, a framework does a well-defined thing with pluggable components, right? And there's already we already kind of have the pluggable components pretty well defined. Like I said, the ledger, the wallet, stuff like that that you can just provide yourself as a consumer. And the only thing that's really standing between the current state of the art and a more consumer friendly approach are these state machines and their complexity. But when you come to think about it, like I was saying before, I'm sure that most of the people that use this right now have used it and will use it in the future they will just want a thing to work. And that kind of brings me to maybe having some sort of interface for handling messages and it kind of ties to the way the message is created has been designed a bit. And it actually makes the state machines it might end up making the state machines simpler. So kind of stick with me here a bit. But it might take a bit longer. So I don't know if you guys have time if now we can maybe discuss this next week. Okay. So the the overall lifetime of a message would be you get the message and then I don't know you might want to you need to kind of see what message it is and get a state machine that's associated to that I don't know that instance of the protocol that you got a message for. And if things match up you basically basically try to process the message, right? And what that would mean is basically that you would have these message handlers that expect a particular message and a particular state machine. And given the fact that we use the type state pattern the state machine would be in a particular state. So you basically put these things in and that's where your messaging process your message processing starts and we can actually separate remember how we were talking about the IO being in the state machine and that's kind of messing things up because the state machines are consuming. Well, what if you actually could do the IO in here but outside of the state machine transition and the state machine transition would pretty much become unfallable because you first try to gather all the pieces that you need to get to the next state. If that fails you never even touch the state machine, right? So there's no need to basically take it out and put it back or return the old state or do whatever you need to do like this whole thing would essentially just not happen because all the IO and all the failures that can occur essentially happen a layer on top of the state machine. And the state machine would basically be there just to keep track of where we are in the protocol which in the end that's what state machines are for. Yeah, so now the beauty of this in a way would be we can provide sort of like default built-in implementations of these message handlers for all the messages that we support and all the states of the state machines which we will ultimately do anyway what we just incorporate that in the state machine itself. But people could maybe also provide their own. Like if you want to override or just use something else for a particular message or you might want to process decorators differently or something like that then you could provide your own implementation and just not use the one from the framework or the library, whatever you want to call it. And this would even abstract away all the stuff in a way because I'm thinking that if we go to this if we go this route to simplify things we could even have this kind of state machine handler the interface of this is debatable again this removed thing was maybe considering the fact that you might want to remove a failed state machine but this can just as well go away and what do you do you just insert it with the failed state and if the user wants to do something with that and remove it they can do it later on it's their problem. But basically given this handler in this process we just take the state like we try to process the pieces before the pieces needed to transition the state machine and then we get it and then we insert it and decide what to do later on. Now this is not a final obviously I literally thought of this this morning so there's a lot of things to figure out like what to do with problem reports and stuff like that that still needs to be thought of but ultimately what this would lead up to is that when you get a message okay you got to match on it to kind of see okay what this message is and what you're supposed to do with it but then you just pass in the message handler you already have the message right because you matched on it you provide a state machine handler that will give you a state machine in a particular state you might want to provide a state machine handler is the one that will take you the state machine out of whatever storage or cache you have and the one and we need an abstraction we need an abstraction over that because the state machines like each individual state machine and each individual state has a different type so it would be best to kind of have that outside. Now here this is basically the idea I don't know if we necessarily need it to be generic we might just use string we might not I don't know but ultimately the idea is that we can handle through this interface the state machine handler we can take care of you know depending on the outcome of the state machine whether you get the new or the old one we can handle putting it just putting it back you know we can get it in the old state we have all the pieces we transition it and then we put it back. There's one more yeah it's interesting idea I mean typically I just need to you got a message the state machine handler and yeah that state machine handler however it needs to based on the message it needs to find that message in whatever storage it's stored Nanomessage the state machine Allright it needs to find the state machine based on the message then that can be something about based on the message ID sometimes can be based on thread ID maybe, I guess there might be a few cases. Okay, let's see. So it finds the message, it needs to understand the store, it needs to understand how the state machines are stored in that store. Right, which is what this handler is for. And save it. But okay, I see like maybe two kind of problems. First is that like it will, there might be a bit of like inefficiency, like since this is doing like stuff for you. Okay. Like, first of all, sorry, I'm just quiet and Yeah, this is all to take in and you definitely need to think about it and putting a complete so you'll need other pieces here, you might need a ledger type, wallet type, some stuff like that. So there are other pieces that are needed. But the point, yeah, go ahead. Like I guess the main thing I'm like, I think I'm considering is these are users like might have like different, like you might want to have more data associated with the state machine, for example, then just the state machine itself, like you want to maybe do some, you know, since especially since we have this philosophy of like, you shouldn't care about what serialized, you know, what serialized state machine looks like. Then if you want to, for example, keep a, you know, collection, like some database of this, I know, proven state machines, and you want to track for each of them, like a number of attributes, like, was it verified? What was the values provided? And, you know, maybe you want to have indices on this field so we can like do filtering and searches and stuff like that. Then, then I'm worried like, like, that this gonna dictate too much. If the state machine handler, this, this get, get insert thing is not gonna dictate too much about how the, you know, the database schema or, you know, Mongo collection or whatever must look like. And I guess there's like some, why would it though? Sorry? Why would it? It's still a trait. You implement this on a type and you could have, you could store whatever you wanted the type and you can design the methods to look exactly like you want. Like you don't necessarily, you were talking about, you know, storing some other metadata. You could do that in this exact same method. Now, again, probably these are going to be async traits as well. I literally just drafted this. So there's a lot. I can imagine like this being like convenient. Yeah. When you're staying in a Rust ecosystem, really, like you're writing on top of this in Rust, that must be great. Or at least could be great. I wonder, I see that there will be like a lot more difficult to work with, kind of work with, if you go through FF file, let's say, you know, you have layers written in JavaScript and then you have some like database handling inside Rust, but then maybe you have some own, you know, in JavaScript as well. It's kind of like, you know, what's happening. And, and, but yeah, okay. Like anyway, long term, like kind of first classes, citizen is Rust. And we are planning to like, you know, long term, if you want to write like issue very far in Rust. So this could be like pretty cool. But if this is like some, if it is like the handler, this stuff becomes kind of like, you know, literally, like this is every VCX. And, and then I'm thinking also, then yeah, it wouldn't be great for FFI. And especially since lots of people are coming from, from the mobile, I wonder who, how this kind of, you know, how this would play with them. I don't know how they typically store the state machines. I think, I think maybe George would have some interesting in, in thoughts on this. I wonder what he would think. How, how convenient from his perspective, or inconvenient, I don't know, would it be to have this kind of handler and, you know, kind of deal with persistence on the, on, on the Rust level, because I'm thinking like maybe, you know, maybe when George is working with state machines, maybe he's putting into some kind of iOS store, you know, if he's, if he's doing that from like upper levels, somewhere from the script, right, he gets a, he's a message, he obsies the state machine, and then he puts it into some sort of, you know, iOS system store. And we don't want to deal with, I don't know, I imagine we, I don't know what's the support for like iOS stuff, you know, from Rust, if you can even do that, if you would even be able to write that kind of handler. Okay, I'm going to stop you for a bit, for a bit Patrick. And I can give you the example of libvcx. So for instance, what we do in libvcx, if I could find it, it's somewhere around here, the one on the core, right, so in libvcx right now, what was it, handle connection, okay, in libvcx, what you actually have is you have this, this cache where you store your objects. And I believe there were some functions for serializing and deserializing, right, state machine. That could be your state machine handler. You don't necessarily have to store this in the database if you don't want to. If you implement this with some type, which has some other methods that look like these, you know, you basically copy paste these into your type, you expose them to FFI if you want. And that's it. And you do whatever you want in the FFI. I don't think this is not flexible enough. I think this is actually kind of very flexible. And even the message handler, you can write your own if you have a particular use case. And just process. But then you, it's basically a conscious decision that you make that you know what this, the implementation that these guys provide is not suitable for me. And I want to do some other crazy stuff with the message or whatever. And that's your business. But like I said, if you think about it, ultimately what most people will do is they're going to match on the message and then do the whatever state machine transition and then handle this result and what else needs to be done. Like it's in, I don't know, maybe 90 out of 100 repository that would be repositories that would be implementing our library, they would all do this exact same thing, which we could abstract away, make their lives easier. And also, you know, because for us, it's easy to deal with this kind of thing where the developers, we know what it means. But consumers, I can guarantee you they're going to ask about it a lot. Okay, well, maybe let's let's not stretch that for too long. I feel like this could be a lot longer, but let's also get like George on this. And then, like, like, just my main concern is like, maybe people want to do like storage and persistence from their respective domain, whether it's in like Java word, Ios word, Node's word, or maybe, I don't know. That's my concern. And maybe then second, second concern is like, actually, and let's, yeah, those could be another, I guess, like further discussion. But another thought is like possible complication is like, when you get the message, typically, like you pass the message to the state machine. And based on if like the processing somewhat completed, you know, you, you, once you know that the message has been processed by a state machine and you got some result, then you want to, you know, using a pickup protocol, this kind of stuff, you want to update the mediator that, you know, you want to update the status of the message, that you don't want to no longer process it. It has been processed. So maybe that would also have to be kind of considered and thought of, if that can be abstracted away, or, you know, how can we, or how can we support it? But I think that can basically also happen outside of this. So, I don't know, like, you could probably, and we're most likely you would return some sort of a result here. So if you got an error, you might not want to update the whatever the message in the, in the mediator, but if you did get an okay or whatever, then you can update it and say that it's processed. Right. But then you need to actually, then you actually need to kind of propagate information about the retribality or not, because maybe if it's retribal, then you might want to, you know, like, you know, that you didn't succeed, the state machine stayed in the previous state, but you just want to retry later and you will need to like, you know, get the message again. Yeah, that's, that's a good point. I think I actually thought about that, but it slipped my mind. Yeah, you probably want kind of the same thing in here, but without dealing with the state machine, right? So you just want to, okay, this is retryable, you can, you can retry later and this is the error or it's aborted and, you know, or it's okay, like the message was processed successful. So it could be something like that. And it would actually make sense, especially in the use case you provided. I think it's a very good point. But nevertheless, like even if, even if you do something like that, I think not having to deal with the state machine is a big win for most of the consumers. Well, I'll think about it. And yeah, I mean, I guess we, let's think about it more. I need to kind of get it through my mind and maybe take some time to process. That's a, that's a good idea as though. And I mean, I'm, I'm, I'm, I'm saying like, you know, that we found off as a library, which I think is the case at the moment, pretty much. But I can imagine like having some like rather a thin layer on top of like this, like the, these like library components we have and state machines to like offload something and then that could be like easier to use. But at the same time, there will be still those like granular components underneath that if somebody Right. And what I'm trying to get at is that then we can basically design this state machine is in a simpler fashion, you know, with the like completely without IO, because we would do them here. And people will also have an example, like, you know, maybe more seasoned developers that want to do stuff their own way. They would also have an example of what they need to do and how it needs to look like and how it works to kind of do with themselves as they want to. And I know they want to have no handlers. Like I don't think it's necessarily taking power out of people's hands, but as much as enabling them to kind of get things working faster. And also kind of making our whole code much easier to reason with, because the state machines right now do a lot of things and it's kind of painful. Whereas here we have the possibility of kind of layering things out in a much easier to follow way. And a much organized matter of dealing with the state machines as well. Oh, yeah, I mean, the IO must be somewhere. It's not is the IO of Yeah, no, it would be here. But this doesn't necessarily have anything to do with the state machine until it transitions itself. So where it transitions it. So for instance, like I was saying here, you would do whatever, I don't know, take, take any, any, any transition that you want. So why can it fail? It can fail because, I know, some some stuff just doesn't add up or some IO error or whatever. Now, all these errors that can occur would be happening before you actually try to transition the state machine. The transition the function on the state machine will only take the parameters it needs and compose the next state an unfallible operation. The fallibility is basically taken out of the transitioning function and into this or maybe some other functions that this this thing calls. So then you no longer return the old state or whatever you do and we're transition to whatever it's it's much easier to follow, I think. Yeah, you might you might have some point and I mean still it would still that's a good point that you said that you can still, for example, integrate this with libvcx, which we want to keep the node.js support and the steam message handler can technically just for before the in memory cache and then you can do persistence in the database or whatever your own way. Right, and it's also a thing to maybe note about this is that the handler like the state machine handler, any any state machine handler can basically be passed in here because it's a generic one the function and it's not an associated type like these things are. So if you just want to store your state machine differently, feel free to do it like I actually believe this is something consumers would implement we wouldn't implement something for them so you might have a different database or you might have whatever so this is something the consumers would implement and just pass in here just as maybe the transport now this and this is also a matter of debate I know we're kind of stretching but whether given this this idea we could still have maybe keep this transport trait and have them or maybe just taking a closure and also send messages or try to send messages from here or maybe problem reports only I don't know and then people could still retry the message sending afterwards so kind of making things more streamlined I don't know it's we're stretching again so there's a lot to discuss about this but but I just wanted to kind of present what I what I was thinking about now I'm going to stop here sorry can you can you share it for back for just two more minutes okay sure we get some last concludes some last thoughts just kind of that great do kind of a little brain dump of my own so that will be the stand machine handler message handler it gets message it gets state machine it gets message gets the handler handler can get the message from somewhere stored back there okay so and we have pretty much we can share the same handler for I guess in pretty much the same handler for many different state machines maybe different configurations because you might want to store different state machines and different tables or collections or files whatever and then you get a message yeah you process that and this thing you get a let's say you get a what's interesting message you get a connection request message you you get the handler for you get a handler for connections basically for that type of message you might not even expect to find anything because somebody simply send you a connection request out of blue so in that case you wouldn't actually in that in that processing you you will actually get something but you would process the message create a state machine you would insert the state machine you would have to actually you might actually want I guess the insert the insert in that case the insert should actually like a return some sort of ID and then process I guess should also kind of propagated because it creates some new new new record in database you want the caller have some control information about it so there'll be like actually interesting case but then what happens then you get a request you in the processing message okay so you create some placeholder state machine in initial state it's a connection request you maybe have to resolve their DID maybe it's somewhere on some ledger or whatever they it can be pretty much anything so you do the ID resolution in that processing you within the world so that's some ledger IO you create the keys in your wallet that's some wallet IO and then lastly like you generate the response for this generate the response a connection response message you send it you find that sending message failed because you are out of internet connection temporarily you might have some I guess retry logic and I guess the processor that's the kind of thing which should be probably configurable so I'm sorry for interrupting I think we can at best try to send it once and people can try to resend it later on like we're still gonna generate the message that's it's still gonna be the way the state machines would be so you generated the response to a connection request you transition the state machine it contains the response we can try to send it once but then people can also retrieve the state machine from the database themselves maybe have some sort of background task that I know if you didn't if you don't get the response to your last reply for or if the state machine has been updated in two days then maybe try to resend the message if there is a message to be sent so we would still like be we would still keep that constraint of not doing like the send response IO in the process method we would only we could do it once but we don't guarantee that it would actually you know do anything we're like I said the the thing with the the state machine states is that we can send the message but we'll never have the confirmation that it was received so by all and we might have like the the thing with having the ability to send messages here is that it might be convenient in the case that we get the problem report that we it might need it to be sent so we could give that to users actually you know what that might be a better idea okay maybe we don't do any message sending at all maybe we just give the resulting messages to the user so good point because then you would have to if you if there's like two outcomes of process like you get connection requests and basically there's two outcomes like either the response or send or not send did I imagine after after calling process me as a caller I check what actually happened which state I am and if I'm not in the you know the I know state which signals successful sending then I have to kind of retry myself possibly or retry nature and that's kind of like complexity so yeah I think the message sending out keep it out of the process like yeah we could probably keep that out if you wanna keep make it responsible so so in that case this would encapsulate the ledger just the position yeah and yeah like getting the pieces to translate state sorry yeah so this process method will basically encapsulate like database read and write of the state machine before and after and in the in the middle that would be processing of the received message possibly results some sort of like ledger like interactions and and like wallets interactions generating keys okay yeah and technically like if you actually if you actually don't yeah if you want if you actually don't want you know the message the handler to deal with the database you can always kind of provide really mock kind of state machine handler which would yes basically do nothing like just memory slot somewhere and it would write the message get the state machine and write it or just write it if nothing was there in the first place which is also the case with the connection request where you don't actually you receive the message but you don't have any state machine to load up here right yeah this could maybe like provide a kind of uniform uh layer on top of state machine this thing that Mira was coming up with but but it didn't seem uniform and like it seems like asymmetric maybe this could be the kind of a shared interface for yeah definitely achieve it for the IO which needs to be done on top of state machines since we want to be right yeah I was thinking about the the framework I think I think I mean in the end people would still have to do this themselves and match on the erase message and whatnot um but I just think like the the overall like we can abstract away some stuff that are really common are kind of our responsibility and are not really something that consumers should deal with you know like the actual message processing while also making the whole interface is nicer anyway I'll think more about it maybe you know also consider what you said and all the possible use cases kind of draw the more complete API but yeah let's leave it that's this and I think we have lots of yeah we can discuss it next week or something yeah and I think this will be this must be like compulsory listening for for charge and Mira so they can get the inputs on this discussions and I think like you are up to something and I think like Mira will also like might also find some some parallels with the problems you know he was struggling in this process method which kind of would uniformly could potentially uniformly encapsulate those the the complexity you want to extract out of state machines put them somewhere on top and maybe this message handle it with that layer right okay all right that was uh that was it then and I think we have one more item in magenta was that it ah no no I don't think so good good close alarm fortunately okay so you guys are all free uh man hopefully I don't know at least like you took something out of this I don't know if you were listening actively it might be kind of like uh I mean confusing or like advanced we already have like lots of context about what we are doing and you're just kind of like meeting every six initially so hopefully it was any any any any good any useful for you as well yes I mean it's sort of like passive learning I guess yeah you like just kind of collect the glimpse of like kind of pattern here and there and it yes exactly yeah okay folks thank you very much for for bearing this really long call and have a great day and wonderful weekends with this incoming see you next time thank you thank you have a good one bye bye