Artefact (Artefact v0.1.5)

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.

Every operation records its lineage in the result's metadata.provenance, validates its inputs, and validates the produced artefact before returning — so corruption fails at the call site rather than five steps downstream.

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 between them.

Compose two artefacts into one. Graphs are concatenated without merging. Nodes remain disjoint; label-based relationships are implicit.

Graft args onto left, integrating new nodes and relationships declared inline (same shape as Artefact.new accepts) without creating a second artefact.

Harmonise two artefacts using declared bindings.

Returns true when value is an %Artefact{} struct.

Returns true when value is a valid artefact (see module docs).

Create a new Artefact. Defaults base_label and title to the short name of the calling module. Override with title: or base_label: in attrs.

Validate an artefact. Returns :ok or {:error, reasons} where reasons is a list of human-readable strings describing each rule violation.

Validate an artefact. Returns :ok or raises ArgumentError with the collected reasons.

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 between them.

Designed for pipelines — heart flows through the pipe as the first argument, so a chain of combines accumulates a single heart from many others:

me_knowing
|> Artefact.combine(me_valuing)
|> Artefact.combine(me_being)
|> Artefact.combine(me_doing, title: "MeMind", description: "Mind of Me.")

Bindings are found via Artefact.Binding.find/2 — every node sharing a uuid between heart and other becomes a binding. Raises MatchError if no bindings are found.

Internally delegates to harmonise/4, so :title and :base_label overrides in opts are honoured. :description is also accepted and applied to the result.

Records :harmonised provenance with the calling module.

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

(macro)

Compose two artefacts into one. Graphs are concatenated without merging. Nodes remain disjoint; label-based relationships are implicit.

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 and the metadata of both source artefacts.

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

(macro)

Graft args onto left, integrating new nodes and relationships declared inline (same shape as Artefact.new accepts) without creating a second artefact.

Designed for pipelines after a series of combines — args flows in as the second argument, with the result's :title and :description named in opts:

our_shells_artefact
|> Artefact.combine(our_manifesto_artefact)
|> Artefact.graft(args, title: "Our Shells and Manifesto",
     description: "Our Shells and Manifesto shape our Association Knowing.")

args

A keyword list with :nodes and :relationships, identical in shape to what Artefact.new accepts inline — except that every node entry must carry an explicit :uuid. There is no auto-find: the uuid is the binding.

Each args node either:

  • Binds to an existing left node (uuid present in left.graph.nodes). Labels are unioned, properties merged with left winning on key conflicts. Position is untouched.

  • Adds a new node (uuid not in left). Receives a fresh sequential id continuing left's offset.

Args relationships use args-local atom keys, just like Artefact.new. Every key referenced by a relationship must be declared in args.nodes.

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.

Raises

Provenance

Records :grafted with the calling module, a summary of left, and right: %{title: <opts.title>, description: <opts.description>} — the result's name as provided.

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

(macro)

Harmonise two artefacts using declared bindings.

Bound nodes are merged: lower uuid wins for identity and properties, labels are unioned. All relationships are preserved and remapped. Returns a new artefact with a portmanteau base_label unless overridden.

Records :harmonised provenance with the calling module and the metadata of both source artefacts.

is_artefact?(arg1)

Returns true when value is an %Artefact{} struct.

is_valid?(value)

Returns true when value is a valid artefact (see module docs).

new(attrs \\ [])

(macro)

Create a new Artefact. 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 — surfaced as Mermaid accDescr and in the ArtefactKino inspector. Defaults to nil; pass it explicitly when you have something to say.

Records :struct provenance with the calling module.

validate(a)

Validate an artefact. Returns :ok or {:error, reasons} where reasons is a list of human-readable strings describing each rule violation.

validate!(value)

Validate an artefact. Returns :ok or raises ArgumentError with the collected reasons.