Glaas minimal logo, light

Tags: roar and GLaaS

On this page

What tags are

Tags are governed, hereditary metadata. A tag records a compliance-relevant fact about an artifact — its license, whether it contains PII, its data-residency jurisdiction — and then flows downstream on its own. Tag a raw dataset contains_pii=present, and every model, checkpoint, and export derived from it inherits that tag through the lineage graph, without you re-stating it at each step.

That inheritance is the whole point. Labels are freeform metadata you attach and maintain. Tags are a small, governed vocabulary that roar propagates for you — so a compliance fact established once at the source can't quietly fall off the record three transforms later.

Tags live under the reserved tag.* namespace inside the same versioned label document, but they are not freeform: they carry per-value provenance (who set each value, and which job it came from) and a bind ledger that controls how far they travel. You interact with them through the dedicated roar tag verb, never through roar label.

Availability. Tags are a roar 0.4.0 feature.

Quick use

roar tag add contains_pii=present   raw.csv        # tag an artifact by path or hash
roar tag add license=Apache-2.0     @2            # tag the output(s) of job step 2
roar tag show      model.pkl                       # show current tags
roar tag history   model.pkl                       # every revision, append-only
roar tag why       contains_pii  model.pkl         # explain how it got this tag
roar tag rm        license=Apache-2.0  @2          # remove one value
roar tag rm        license             @2          # remove the whole kind
roar tag bind      model.pkl                        # promote its tags across sessions
roar tag unbind    model.pkl                        # revoke that promotion

Targets are the same everywhere: @N is job step N in the active session; a path or hash prefix is an artifact.

Canonical kinds

Tags are restricted to a small canonical vocabulary, because a typo'd kind (licence, pii_present) is a compliance fact that silently doesn't propagate and doesn't match a search. The built-in kinds are:

KindMeaning
licenseDistribution license of the artifact
contains_piiWhether the artifact contains personal data
jurisdictionData-residency / legal jurisdiction
classificationSensitivity classification
special_categoryGDPR Art. 9 / special-category data

roar tag add rejects an unknown kind by default and tells you exactly how to allow it. If your organization has its own vocabulary, opt in per-project with a .roarconfig:

[tags]
custom_kinds = ["export_control", "retention_class"]

Custom kinds are additive — they extend the canonical set rather than replace it, and the append-aware error message spells out the two lines to add so you don't have to guess the format.

Heredity: how tags propagate

Within a session, tags propagate automatically from a job's inputs to its outputs. Run a training job whose input dataset is tagged contains_pii=present, and the model it produces is tagged contains_pii=present too — marked as inherited (origin=system) and stamped with the producing job, so the record shows the value wasn't a fresh human assertion but a consequence of the lineage.

Each value therefore carries where it came from:

  • origin=user — a human act: a bare roar tag add, or roar run --add-tag.
  • origin=system — inherited via propagation at job-record time, annotated with the job that carried it.

Propagation is deliberately over-approximate within a session (a false positive is cheap and safe; a false negative is a compliance miss). It is a union: an artifact accumulates every value it inherits, and roar tag rm never rewrites history — it just stops a value from propagating forward.

Crossing sessions: bind

Automatic propagation stops at the session boundary. Crossing it requires an explicit bind — a human act naming the concrete artifact whose tags are of record. This is what stops a stray 0-byte or scratch artifact from one project infecting everyone else's work: tags don't leak across sessions, users, or organizations unless someone deliberately promotes them.

  • roar tag add on a named artifact is born bound — naming a concrete, inspectable artifact is itself the human act, so it writes an implicit bind covering exactly the value you added.
  • roar run --add-tag stays session-scoped until you bind the artifact — it stamps the output within the run but doesn't promise anything cross-session.
  • roar tag bind <artifact> promotes an artifact's current tag set to cross-session scope; roar tag unbind revokes it.
  • roar register --bind / --no-bind controls whether registering to GLaaS promotes the artifact's tags.

The bind ledger is append-only: bind and unbind write events, they never delete. One unbind heals the whole downstream cone — everything that inherited through a revoked bind becomes mechanically identifiable as superseded. roar tag bind echoes what it promotes (path, size, and the tag set) so binding junk means reading past a line telling you the artifact is empty.

Explaining a tag: roar tag why

Compliance is about accountability, so every inherited tag can be traced back to the human act that originated it:

roar tag why contains_pii model.pkl
# Why does model.pkl have contains_pii?
#   model.pkl  contains_pii=present  (inherited from job train.py)
#     └─ raw.csv  contains_pii=present  (tag add — user)

roar tag why walks the inheritance path back to the originating tag add / run --add-tag, annotating any cross-session hop with the explicit bind that authorized it. It explains an artifact's tag; point it at an artifact (by path or hash), not a job step.

Barriers on roar run

Sometimes inheritance shouldn't happen — a step genuinely strips PII, or produces a differently-licensed output. Two run modifiers shape what a job records:

roar run --block-tag contains_pii        -- python anonymize.py   # stop a kind from inheriting
roar run --block-tag license=GPL-3.0     -- python build.py       # stop one value
roar run --add-tag  contains_pii=absent  -- python anonymize.py   # assert a value on the outputs

--block-tag KIND blocks a whole kind from propagating into this job's outputs; --block-tag KIND=VALUE blocks a single value; --add-tag KIND=VALUE stamps a value.

These modifiers are recorded on the job and replayed by roar reproduce. A barrier is a property of the job, not a flag you have to remember — so reproducing a pipeline reproduces the tag layer faithfully, instead of silently re-inheriting a tag you had deliberately blocked.

Seeing tags

Both roar show and roar tag show render tags the same way — a clean Tags section listing kind: value1, value2, with the internal bind ledger hidden. Jobs additionally show a Barriers section when they carried --block-tag modifiers. roar tag history shows every version of the tag document, append-only.

Visibility

Tags follow the scope of the artifact they're attached to, exactly like labels:

Scope of the artifactTag readable to …
anonymouspublic
publicpublic
privateyou only
<owner>/<project>project members only

A tag on a private artifact is invisible outside that scope — GLaaS never returns a tag to someone who can't already read the artifact it's on. There is no way to make an artifact private but its tags public; the tag inherits the artifact's visibility.

Tags on glaas.ai

When you roar register a tagged artifact, its tags travel with it. On glaas.ai the artifact's record carries its tags — following the scope rules above — so the license and PII status you established at the source are visible on the registered artifact for anyone entitled to see it. This is what turns a private, per-repo convention into an organization-wide compliance record, and feeds the audit / AI-BOM view of what a model is actually built from.

Where to look next

  • Labels — freeform metadata; tags are the governed, hereditary subset under tag.*.
  • Scopes — how tag visibility, and the bind boundary, follow scope.
  • Audit (AI-BOM) — tags as part of the bill of materials for a model.
  • roar Guide — the full roar tag command reference.