Files
root-at-skic 99ea076571 Model graph: decisions and registry files as nodes
- one node per decision (tag coloured by status) with decides links to its elements and supersedes links
- one node per registry file with defines links to its elements
- own legend chips, side panels (Open decision, Open registry), type:decision and type:registry
- walks and paths follow the diagrams' connections only; attached nodes follow their elements into a result
2026-10-21 20:46:05 +03:00

8.0 KiB

Models: the file formats

A model is a folder of diagrams that belong together: a main.archify at its top, any number of diagrams below it, and *.archify-registry files for the things several diagrams share. Three file kinds, all YAML, all read by the extension; Archify itself only ever sees plain diagrams.

main.archify

schema_version: 1
model:
  id: online-shop
  name: Online Shop
  description: >
    Web shop, its API, workers and stores.

Optionally, below the model block, a diagram exactly as in any other .archify file (diagram_type, meta, components, …). The extension shows it on the model page; Archify never sees the model block.

name.archify-registry

schema_version: 1
elements:
  api:
    type: backend
    label: API
    sublabel: REST service
    brand: node-js
    description: >
      Node.js service behind the load balancer.
    diagram: 0300-components/api.archify
  db:
    type: database
    label: Database
    sublabel: PostgreSQL
    brand: postgresql
    description: Orders, customers and catalogue.
  • The key is the element's id, unique across all registry files of the model.
  • type, label, sublabel, tag, icon, brand, sources are Archify's component fields and are copied into every diagram that refers to the element.
  • description is the one description of the thing; shown on hover and on the model page, never sent to Archify.
  • diagram is the link: the diagram that explains the element, relative to the model root. Clicking the element in any diagram opens it.

A diagram that refers to the registry

components:
  - ref: api
    pos: [250, 160]
    size: [130, 60]
  - ref: db
    label: Orders DB           # a diagram may override label, sublabel, tag
    pos: [460, 260]
    size: [130, 60]
  - id: cron                   # an unshared element, inline, as today
    type: backend
    label: Nightly job
    pos: [460, 420]
    size: [130, 60]
  • ref names a registry element; id defaults to the same name. id: db-replica with ref: db draws the same element twice or under another id.
  • A diagram may override label, sublabel and tag; never type or brand (if those differ, it is a different element).
  • Before Archify runs, the extension replaces each ref component with the registry element plus the diagram's own fields, drops description and diagram, and hands Archify an ordinary component.
  • Connections, boundaries and everything else stay as they are and use the ids as before.

Descriptions under a model diagram

Archify's Elements panel under a diagram lists its nodes. For a ref component the row's tooltip is the element's registry description. Archify's own cards: stay what they are: write them in the diagram when you want text blocks below it; nothing is generated.

A diagram may point at another diagram from a component, whether shared or inline:

  - ref: api
    pos: [250, 160]
    size: [130, 60]
    diagram: 0300-components/api.archify   # overrides the registry's link for this diagram

Registry diagram links and component diagram links are the same mechanism; the component's wins when both exist. Paths are relative to the model root.

Outside a model

A diagram with ref components outside any model (no main.archify above it) reports "no registry found" and shows the component by its ref name with type external, so the picture still renders.

Starting a model

Archify | New Model… (right-click a folder, File → New File…, Command Palette) offers three complete examples: C4 - Standard Web App, C4 - E-Shop and C4 - Event-Based Integration. Pick one and a folder name; the example is copied into that folder with model.id, model.name and the overview title taken from the folder name (an example kept under its own name is copied as is). Each example has registry/{people,systems,containers}.archify-registry and diagrams under 0100-context, 0200-containers and 0300-components; every registry element is used by at least one diagram and every diagram validates.

Decisions

An architecture decision is one *.archify-decision file, anywhere under the model root (decisions/ is the convention):

schema_version: 1
decision:
  id: queue-between-api-and-worker   # unique in the model, any short string
  title: A queue between the API and the worker
  status: accepted                   # proposed | accepted | superseded | rejected
  date: 2026-09-16
  elements: [api, queue, worker]     # registry ids
  diagrams: [0200-containers/online-shop.archify]
  supersedes: []                     # ids of older decisions this one replaces
context: >
  Why a decision was needed.
decision: >
  What was decided.
consequences: >
  What becomes easier, harder, or must change.

Ids are strings; an unquoted number such as 0001 is refused because YAML reads it as 1. A decision another decision supersedes shows as superseded whatever its own status says. Unknown elements, missing diagrams, duplicate ids, unknown statuses and dangling supersedes are problems on the decision file.

Diagrams point back at decisions with a decisions list of ids on the diagram itself, on a component (or node, participant, state) and on a connection (or edge, flow, transition, message):

decisions: [postgres-as-source-of-truth]
components:
  - ref: queue
    pos: [460, 360]
    size: [130, 60]
    decisions: [queue-between-api-and-worker]
connections:
  - { from: api, to: queue, label: enqueue, decisions: [queue-between-api-and-worker] }

The key is stripped before Archify renders. An unknown id is a problem at its line; outside a model the key is an error, like ref. The main.archify page lists all decisions; a diagram page lists the ones it points at or that name it; an element's card and dialog list the decisions about it. A .archify-decision file opens as its own page. Outside a model it still opens, with a note that it has lost its model.

The model graph

The Model | Graph switch on the main.archify page replaces it with the whole model as one graph. It is built from the model index, not from Archify's renderer:

  • Nodes are every element any diagram draws (components, nodes, participants, states), joined by id across diagrams, plus every registry element even when no diagram draws it yet. Registry elements carry their description, file and line; inline elements only what the diagram says. The same inline id in two diagrams is one node.
  • Edges are every connections, edges, flows, transitions and messages entry between two nodes of the same diagram, keyed by from>to; the labels different diagrams give the same pair are joined with " / ". Direction is kept.
  • Decisions reach nodes through elements: in the decision file and through decisions: on a node in a diagram; they reach edges through decisions: on a connection.
  • Decision nodes (decision:<id>, type decision) carry the effective status, the context and decision text, and the diagrams the decision names; decides edges point at the elements it is about, supersedes edges at the decisions it replaces.
  • Registry nodes (registry:<file>, type registry) stand for each .archify-registry file; defines edges point at its elements.

Walks (uses:, near:, from: to:) follow connection edges only. Decision and registry nodes join a result when an element they link to matches, and -type:decision or -type:registry removes them.

Queries run in the page against that graph; the forms are listed under ? on the page and in the README. uses: and near: ignore direction; from: to: follows the arrows first and ignores them only when no directed path exists. Connections are shown when both ends match, so type:backend shows backend-to-backend connections only.

The switch is remembered per main.archify in the workspace. The graph page updates in place when a file of the model changes: elements that are still there keep their position, new ones are laid out around them.