-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
docs: 0008 validation refactor adr #881
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great. Thank you! :)
I've added just one comment about coupling the interfaces to an implementation of the ValdiationStore that may carry logic that may not be related to these new semantics.
adr/0008-validation-refactor.md
Outdated
type ValidationProducer interface { | ||
// Populate populates the validation store with the validations from the producer | ||
// as well as the associated requirements, as defined by the producer | ||
Populate(store *ValidationStore) error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How much of the ValidationStore
is really related to the Requirements
interface? (I'm guessing the implementations of the producer will probably end up calling the AddRequirement
methods?). Looking at the current wip branch I can see that most of the logic in the store is not related to them.
WDYT then, about extracting an interface for the ValidationStore
as well, exposing the methods that are relevant for new Validation interfaces? This way these new interfaces will not be coupled to existing logic in the store that is not really related to this validation semantics.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the suggestion! I've been chewing on this and trying to figure out the implications. I'm wondering if the intended effect would basically be like "you can put any validation in the validation store, it doesn't need to be a LulaValidation"? Looking at the usage of the ValidationStore right now, seems very specific to the fact that there are LulaValidations in there, so I'm just trying to figure out how that would be generalized... PS if you have direct changes/suggestions on how to do this feel free to comment them in the branch!
My thought process behind sticking requirements in the validation store was mostly that a context-less validation (i.e., one without the thing it's proving) feels like not actually a validation, so conceptually (to me anyway) it made sense to stick them together. The other thing I was trying to do was knit the producer (who creates the requirements) to the consumer (who reports out the results of the requirements) by creating that single interface (well not interface) of the ValidationStore, so they don't depend on each other directly.
Again, there is most likely a better design to doing all this, if you do want to make suggestions directly in the code, I think much better when seeing the actual thing in action 😁
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I have a couple follow-up questions, mostly driven because there are three interfaces here that are completely independent, although internally they seem to be tightly related, and that is a bit confusing to me :)
If the idea is that "you can put any validation in the validation store", why is the Requirement
interface needed at all? I mean, if the Producer and Consumer don't use it, why does it even exist?
Following this line, would it make sense for the Populate method to receive as an argument, not the validation store, but some interface that "accepts requirements"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the idea is that "you can put any validation in the validation store"
Sorry if there was some confusion about that - I meant to ask it as a question to you, if that's what you were intending with the request of an interface. I think that only Lula Validations should go in the validation store, and the Lula Validation engine executes them, which is why I was hesitant to make that an interface, there's just a lot of stuff that feel particular to those that would make an interface there challenging.
if the Producer and Consumer don't use it, why does it even exist
The producer and consumer are using the requirements - essentially the Requirement
interface is populated by the Producer
and used/reported on by the Consumer
, and the reporting or evaluation of those requirements is a function of the results of the validations. So a couple instances I tried to draw out in the WIP branch are:
- The ComponentDefinition establishes the components of the system which perform the controls, e.g., AC-1, AC-2. The
Requirement
(so calledComponentDefinitionRequirement
) is successful when each component that performs a control (because there can be several) are all linked to validations AND those validations are all passing. The ComponentDefinition producer populates the requirements from its spec, and the AssessmentResults consumer yields the results of the requirements in the format particular to its spec - The Simple case is trying to illustrate a much more straightforward "requirement" where essentially the requirement is a simple pass/fail if all corresponding validations pass or fail.
After looking a bit more though, I do think possibly sticking requirements in the validation store is just a little lazy on my part, and perhaps breaking them into like a RequirementsStore to have separate methods would make a bit more sense.
I'm going to try and make a couple changes, and include the comment below about EvaluateResults
, in the WIP branch and will make the according changes here 😄 thank you for the feedback so far, much appreciated!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One nit, otherwise lgtm :)
Co-authored-by: Maciej Szulik <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the clarifications!
I better understand the rationale now, and I like the semantics these three interfaces bring. Nice! 😄
I just have some small follow-up questions about the relationship between these interfaces.
adr/0008-validation-refactor.md
Outdated
type ValidationProducer interface { | ||
// Populate populates the validation store with the validations from the producer | ||
// as well as the associated requirements, as defined by the producer | ||
Populate(store *ValidationStore) error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I have a couple follow-up questions, mostly driven because there are three interfaces here that are completely independent, although internally they seem to be tightly related, and that is a bit confusing to me :)
If the idea is that "you can put any validation in the validation store", why is the Requirement
interface needed at all? I mean, if the Producer and Consumer don't use it, why does it even exist?
Following this line, would it make sense for the Populate method to receive as an argument, not the validation store, but some interface that "accepts requirements"?
adr/0008-validation-refactor.md
Outdated
// Evaluate Results are the custom implementation for the consumer, which should take the | ||
// requirements, as specified by the producer, plus the data in the validation store | ||
// and evaluate them + generate the output | ||
EvaluateResults(store *ValidationStore) error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense for this method to return the results as well? For example it could return each Requirement ID with the evaluation result. Otherwise getting the details of the actual results is hidden in internal state and hard to consume. WDYT?
@nacx - I made a few updates to the wip branch, and this doc:
|
The proposed interfaces look good and help better conceptualize the whole thing outside the context of a CLI. There is another point, probably more internal, that is one of the main challenges when trying to use Lula outside of the context of the CLI: the Refactoring the |
Description
ADR for Validation library refactor
Sample branch and PR (for commentary on specific usage/methods): #882
Related Issue
Fixes #858
Type of change
Checklist before merging