Repository navigation
feat: a digest of a spec's interface, and a check that a changed interface gets a new version - #193
Merged
Merged
Conversation
…rface gets a new version An outputs or params model can change under the same spec name and version, and a record made with the old models is then read into the new classes without an error (ADR 0009). WorkflowSpec.digest is a short hash of the name, type, and requiredness of every field of both models, at any depth, so that such a change can be detected. Titles, descriptions, defaults, constraints, validators, field order, and class names and modules do not change it. ess.spec.testing.check_digests compares each spec's digest with a JSON file kept in the package, so that a model changed without a new version fails in the author's tests; write_digests writes the file. LoKI keeps its digests next to its spec tests. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…vers every entry A RootModel is described by its root type, and a class that is not a group by its module and qualified name, so two classes of one name no longer share a digest. A Literal and an enum of the same values have one description. A group's extra setting counts. An unresolved type raises, naming the field, instead of hashing its repr. A params type with a serializer written with Annotated is refused, as a decorator serializer is. check_digests fails for a file entry of no given spec, and both functions refuse two specs of one name and version. LoKI's iofq digest changes with the Literal form. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #192 (base branch
184-adr-what-is-durable). Merge #192 first, or this PR lands in that branch, not inmain.First part of ADR 0009: a digest of a spec's interface in
ess.spec, and a check for technique packages. Nothing iness.appschanges yet; the next PR stores the digest in a workspace's log and reads a record of another spec as plain data.The digest.
WorkflowSpec.digestis a short hash of the name, type, and requiredness of every field of the params and outputs models, including the fields of groups nested in them. Two specs have the same digest when a request and an output stored under one still fit the models of the other.What counts and what does not:
Literalor an enumRootModel; module and name of any other classThe check. A technique package keeps its specs' digests in a file and compares them in its tests, so a changed model without a new version fails in the author's CI:
The file's entries must match the given specs exactly. LoKI has the file and the test.
Choices to be aware of.
Referenced[T]counts byT's fields. ReplacingTby another class with the same fields keeps the digest; that case is caught when an old reference is checked, since a reference fits by class.Annotated, as they already refuse serializers written as decorators: they change the stored form unseen. A type that is not resolved raises an error that names the field.Review. A fresh reviewer probed for specs with equal digests whose stored forms differ, and for digests that change without reason. Fixed from it: a class that is not a group was described by its bare name, so two
RootModelclasses of one name with different content had the same digest; unresolved forward references were hashed by their text; the check passed when given no specs. The digest does not depend on the hash seed or on how a union or a list is spelled (Optional[X]andX | Noneagree).Not done here. The serialized form of a spec does not carry the digest; that is settled where the digest is first compared, in the next PR.
🤖 Generated with Claude Code