v0.2.0
0.2.0 — 2026-05-05 (breaking)
Artefact
API shape
- All public ops now have two variants:
new/1,compose/3,combine/3,harmonise/4,graft/3return{:ok, %Artefact{}} | {:error, error}.new!/1,compose!/3,combine!/3,harmonise!/4,graft!/3return%Artefact{}directly or raise the error struct. Behaviour matches 0.1.5's raise-everywhere — the!variants are the gentle migration path.
validate/1shape::ok | {:error, %Artefact.Error.Invalid{reasons: [...]}}(was{:error, [reason_strings]}).validate!/1raisesArtefact.Error.Invalid(wasArgumentError).- Closes #23, #25.
Errors as structured values
- New
:sploderuntime dependency ({:splode, "~> 0.3"}). Artefact.Error— Splode root with two error classes (:invalid,:operation).Artefact.Error.Invalid— validation rule violations;:reasonsfield carries the list of human-readable strings.Artefact.Error.Operation— op-specific outcomes;:op,:tag,:detailsfields. SeeMIGRATION.mdfor the full per-op tag table.- Errors are real Elixir exceptions — raisable by the
!variants, pattern-matchable as struct values from the non-!variants, and aggregatable by Splode-using callers (e.g. UsTwo libraries).
Module reorg (internal)
Artefact.Op— implementation home for the operations.Artefact.Validator— implementation home for validation rules; surfaced viadefdelegatefromArtefact.- The
Artefactmodule is now a thin macro facade plus the%Artefact{}struct definition. Future internal refactors won't churn the consumer-visible surface.
Migration
See MIGRATION.md for the migration guide. TL;DR — append ! to every op call and you're done; use the non-! variant + with/case if you want explicit error handling.
ArtefactKino
- Bumps
artefactrequirement to~> 0.2.0.ArtefactKino.new/1,2continues to validate its input viaArtefact.validate!/1, which now raisesArtefact.Error.Invalidinstead ofArgumentErrorwhen an invalid artefact is passed in. Behaviour is otherwise unchanged.