Artefact (Artefact v0.2.0)

Copy Markdown View Source

A knowledge graph fragment — a small, self-contained piece of knowledge expressed as a property graph.

The canonical form is the %Artefact{} struct. Arrows JSON and Cypher are derived representations: JSON for interchange and visual editing, Cypher for persistence.

Operations

  • new/1 — build an artefact, inline (:nodes + :relationships) or from a pre-built %Artefact.Graph{}.
  • compose/3 — concatenate two artefacts; nodes remain disjoint.
  • combine/3 — pipeline-friendly union; bindings auto-found via shared uuid; delegates to harmonise/4.
  • harmonise/4 — union via declared bindings; lower uuid wins identity, labels are unioned, left wins on property conflict.
  • graft/3 — pipeline-friendly extension; integrates inline args (same shape as new's inline form, but every node MUST carry :uuid) into an existing artefact.

Each op has two variants:

  • op/n returns {:ok, %Artefact{}} | {:error, error} where error is Artefact.Error.Invalid (a validation rule was violated) or Artefact.Error.Operation (an op-specific outcome — e.g. combine with no shared bindings, graft with disconnected islands).

  • op!/n returns the %Artefact{} directly or raises the error struct. Use when you'd rather let exceptions propagate (livebooks, scripts, tests).

Every operation records its lineage in the result's metadata.provenance and validates its inputs and the produced artefact.

Validation

An artefact is valid when its uuid is a UUIDv7, every node has a UUIDv7 uuid, every node's labels is a list of strings, every node's properties is a map, every relationship's from_id and to_id reference an extant node, every relationship type is a non-empty string, and node uuids, node ids and relationship ids are unique within the graph.

Exporting

  • Artefact.Arrows — round-trip with arrows.app via from_json/2, from_json!/2, to_json/1.
  • Artefact.Cypher — derive Cypher (CREATE or MERGE) for Neo4j persistence, with parameterised variants for driver use.

Summary

Functions

Combine other into heart using bindings auto-found via shared uuid.

Same as combine/3 but raises on failure.

Compose two artefacts. Graphs are concatenated without merging. Returns {:ok, %Artefact{}} or {:error, %Artefact.Error.Invalid{}}.

Same as compose/3 but raises on failure.

Graft args onto left, integrating new nodes and relationships declared inline (same shape as Artefact.new accepts). Every args node MUST carry an explicit :uuid — uuid is the binding.

Same as graft/3 but raises on failure.

Harmonise two artefacts using declared bindings.

Same as harmonise/4 but raises on failure.

Create a new Artefact. Returns {:ok, %Artefact{}} or {:error, %Artefact.Error.Invalid{}}.

Same as new/1 but raises Artefact.Error.Invalid on failure.

Types

t()

@type t() :: %Artefact{
  base_label: String.t() | nil,
  description: String.t() | nil,
  graph: Artefact.Graph.t(),
  id: String.t(),
  metadata: map(),
  style: atom() | nil,
  title: String.t() | nil,
  uuid: String.t()
}

Functions

combine(heart, other, opts \\ [])

(macro)

Combine other into heart using bindings auto-found via shared uuid.

Returns {:ok, %Artefact{}} or {:error, error} where error is Artefact.Error.Invalid or Artefact.Error.Operation with tag: :no_shared_bindings if heart and other share no node uuids.

Designed for pipelines:

with {:ok, knowing}     <- Artefact.combine(my_knowing, my_valuing),
     {:ok, being}       <- Artefact.combine(knowing, my_being),
     {:ok, mind}        <- Artefact.combine(being, my_doing,
                             title: "MeMind", description: "Mind of Me.") do
  ...
end

Or with combine!/3 if you'd rather let it raise.

Records :harmonised provenance with the calling module.

combine!(heart, other, opts \\ [])

(macro)

Same as combine/3 but raises on failure.

compose(a1, a2, opts \\ [])

(macro)

Compose two artefacts. Graphs are concatenated without merging. Returns {:ok, %Artefact{}} or {:error, %Artefact.Error.Invalid{}}.

base_label defaults to the portmanteau of both artefacts' base_labels. Override with base_label: or title: in opts.

Records :composed provenance with the calling module.

compose!(a1, a2, opts \\ [])

(macro)

Same as compose/3 but raises on failure.

graft(left, args, opts \\ [])

(macro)

Graft args onto left, integrating new nodes and relationships declared inline (same shape as Artefact.new accepts). Every args node MUST carry an explicit :uuid — uuid is the binding.

Returns {:ok, %Artefact{}} or {:error, error} where error is Artefact.Error.Invalid or Artefact.Error.Operation with one of :missing_uuid, :invalid_uuid, :invalid_labels, :invalid_properties, :duplicate_keys, :unknown_rel_key, or :islands (new nodes that don't reach a bind-only key).

opts

Honours :title and :description only — both name the result. If omitted, left's title and description carry forward. :base_label is not honoured; the result keeps left.base_label.

Records :grafted provenance with the calling module.

graft!(left, args, opts \\ [])

(macro)

Same as graft/3 but raises on failure.

harmonise(a1, a2, bindings, opts \\ [])

(macro)

Harmonise two artefacts using declared bindings.

Returns {:ok, %Artefact{}} or {:error, error} where error is Artefact.Error.Invalid or Artefact.Error.Operation with tag: :self_harmonise (same artefact) or tag: :same_base_label.

Bound nodes are merged: lower uuid wins for identity and properties, labels are unioned. All relationships are preserved and remapped.

Records :harmonised provenance with the calling module.

harmonise!(a1, a2, bindings, opts \\ [])

(macro)

Same as harmonise/4 but raises on failure.

is_artefact?(value)

See Artefact.Validator.is_artefact?/1.

is_valid?(value)

See Artefact.Validator.is_valid?/1.

new(attrs \\ [])

(macro)

Create a new Artefact. Returns {:ok, %Artefact{}} or {:error, %Artefact.Error.Invalid{}}.

Defaults base_label and title to the short name of the calling module. Override with title: or base_label: in attrs. Optional description: is a longer human-readable note about the artefact.

Records :struct provenance with the calling module.

new!(attrs \\ [])

(macro)

Same as new/1 but raises Artefact.Error.Invalid on failure.

validate(value)

See Artefact.Validator.validate/1.

validate!(value)

See Artefact.Validator.validate!/1.