# The DALICC user manual

Part of the [documentation index](../README.md#documentation).

DALICC is a service for working with licenses as data: a curated library of license
models, tools that read them, compare them and check whether they fit together, and a
composer that writes a new license of your own. This is the manual for all of it.

**Who it is for.** Anybody using the website, and anybody calling the API with a
personal token. No prior knowledge of RDF is needed; the parts that need it say so. A
shorter tour of what DALICC is and what each tool does is in
[INTRODUCTION.md](INTRODUCTION.md). The HTTP contract is in [API.md](API.md) and the
Python client in [SDK.md](SDK.md).

**If you administer an installation**, the pages under `/admin` are in
[ADMINISTRATION.md](ADMINISTRATION.md). Installing the service and running the server
are an operator's work: [DEPLOYMENT.md](DEPLOYMENT.md) and
[OPERATIONS.md](OPERATIONS.md).

**What DALICC does not do.** It is not legal advice. Every model is a reading of a
legal text, the compatibility checker answers from the axioms it was given, and a
disclaimer on the site says so. Get legal advice before you rely on any of it.

## How do I ...?

| I want to | Go to |
|---|---|
| find a license by name | [Find a license](#2-find-a-license) |
| understand what a license allows | [Read a license page](#3-read-a-license-page) |
| find a license by what I need to do | [Search by what you need to do](#4-search-by-what-you-need-to-do) |
| see two or more licenses next to each other | [Compare licenses](#5-compare-licenses) |
| know whether I may combine these licenses | [Check whether licenses fit together](#6-check-whether-licenses-fit-together) |
| understand how the checker decides that two licenses conflict | [Concepts](#11-concepts) |
| write a license of my own | [Compose a license](#7-compose-a-license) |
| publish my license and share it with a colleague | [Your licenses](#17-your-licenses-roles-sharing-and-versions) |
| check the dependencies of a code repository | [Check a repository's dependencies](#8-check-a-repositorys-dependencies) |
| keep a shortlist of licenses | [My Bookmarks](#9-my-bookmarks) |
| look up what a DALICC term means | [The DALICC vocabulary](#10-the-dalicc-vocabulary) |
| get an account | [Invitations and signing up](#13-invitations) |
| change the name my licenses are published under | [The name you publish under](#the-name-you-publish-under) |
| create an API token and call the API | [API tokens](#16-api-tokens-and-calling-the-api) |
| read the graph the checker reasons with | [Dependency graphs](#18-dependency-graphs) |
| reason with my own compatibility rules | [Dependency graphs](#18-dependency-graphs) |
| turn a license text into a model and keep the draft | [Text-to-License](#19-text-to-license) |
| read a license model back as a license text | [License-to-Text](#19a-license-to-text) |
| offer my license for the curated library | [Submissions](#20-submissions-correction-requests-and-the-inbox) |
| report that a curated record is wrong | [Correction requests](#20-submissions-correction-requests-and-the-inbox) |
| see how much of the API I have used | [API limits and usage](#21-api-limits-and-usage) |
| take a copy of my data, or delete my account | [Your data](#22-your-data) |
| find the address of a page | [Where to find things](#23-where-to-find-things) |
| know what a word such as port, variant or restriction means here | [Glossary](#24-glossary) |
| invite somebody, reset a password, deactivate an account | [Accounts and invitations](ADMINISTRATION.md#2-accounts-and-invitations) |
| correct a curated license record | [Curated license records](ADMINISTRATION.md#4-curated-license-records) |
| write a blog post | [The blog and the media library](ADMINISTRATION.md#6-the-blog-and-the-media-library) |
| raise or lower what one account may ask of the API | [API usage and per-account limits](ADMINISTRATION.md#7-api-usage-and-per-account-limits) |
| read the record of what changed | [The audit log](ADMINISTRATION.md#10-the-audit-log) |
| create the first administrator | [DEPLOYMENT.md](DEPLOYMENT.md#34-the-first-start-and-the-first-administrator) |
| back the installation up | [OPERATIONS.md](OPERATIONS.md#3-backup-and-restore) |
| look up a setting | [DEPLOYMENT.md](DEPLOYMENT.md#4-environment-variable-reference) |

---

## 1. What DALICC is

Four things, in one application:

* **A license library.** 581 records, of which 290 are distinct licenses and 289 are
  ports and editions of them. A *jurisdiction port* is a license adapted to another
  country's law; an *edition* is the same text reissued by another body in the same
  legal system. Two more are test fixtures and are kept out of the lists and the counts. Each record is a
  model: the asset types it covers, what it permits, what it prohibits, the duties that
  ride on each permission, and the warranty and liability text quoted from the license.
* **Tools that read the models.** A faceted search, a side by side comparator, a
  compatibility checker for a bundle of licenses, and a checker for the dependencies of
  a code repository.
* **A composer.** A guided form that writes a license of your own and publishes it at a
  permanent address.
* **An API.** Everything the site does, the API does too, with the same data; see
  [API.md](API.md).

Nothing on the site needs an account except your own licenses, your own dependency
graphs, Text-to-License and License-to-Text (unless the installation opens them to
everybody), submissions, correction requests, the inbox and the administration pages.
Accounts come by invitation unless the installation has opened sign-up, which is covered
from section 11 on.

**Identifiers.** A curated license has a readable identifier (`MIT`, `Apache-2.0`,
`CC-BY-4.0`) and a permanent address, `https://dalicc.net/licenselibrary/<id>`. A
license you compose gets a random 32 character identifier at the same kind of address.
That address is the license: it resolves for a browser as a page and for a machine as
RDF.

---

## 2. Find a license

**By name.** `/license-library` is the list. The box at the top filters by keyword as
you type (and without JavaScript when you press the button). The list shows one row per
license, with its jurisdiction ports folded underneath: a row saying "12 jurisdiction
ports" expands to the ports with their country and the version of the license text they
model. *Show all records* (`?ports=all`) flattens the list again. The state of the list
is in the address, so you can share the view you are looking at by copying the link.

A keyword matches ports as well as parents, and a matching port is shown under its
parent even when the parent itself does not match.

**What the box searches.** A record matches when every word you type occurs, in any
case, in one of its names:

* the title (`The MIT License`),
* the alternative names the record lists (`MIT`, `GNU GPL v2 or later`, `CC BY-SA 4.0`),
* its SPDX identifier (`ODbL-1.0` finds the ODC Open Database License, `CC0-1.0` the CC0
  1.0 Universal dedication),
* its DALICC identifier, typed in full (`OdcOpenDatabaseLicense`),
* an SPDX identifier the SPDX license list has retired, read through the same table as
  the identifier box below: `GPL-2.0` finds `GPL-2.0-only`, `GPL-2.0+` finds
  `GPL-2.0-or-later`,
* a DALICC identifier retired on 2023-04-24, which finds the record that replaced it:
  `ArtisticLicense20` finds `Artistic-2.0`, `AcademicFreeLicense30` finds `AFL-3.0`.

Two words may match two different names of the same record. The results are ranked by
the best of a record's names: a query that is exactly an identifier or a name comes
first, then the records whose names hold every word you typed, the closest name first, so
"mit license" puts The MIT License above CMU License and X11 License. Editions that match
equally well come newest first, so "cc by sa" lists CC BY-SA 4.0 before 3.0, 2.5, 2.0 and
1.0. The punctuation of an identifier counts, because `GPL-2.0` and `GPL-2.0+` are two
different licenses.

**When nothing matches.** A typo is the usual reason. The page then names your query
(No license matches "apahce") and offers up to three licenses whose names come closest:
"Did you mean Apache License 1.0, Apache License, Version 1.1 or Apache License, Version
2.0?", each a link to its page. The autocomplete under the box offers the same titles.
Jurisdiction ports are never offered there, and a query that resembles no name gets no
suggestion at all.

**By identifier.** *Open an unlisted license* on the same page takes an identifier and
sends you straight to the license. It accepts

* a DALICC identifier (`Apache-2.0`),
* an SPDX identifier, as a fallback when the DALICC one does not match, including one
  the SPDX license list has deprecated: `GPL-2.0` opens `GPL-2.0-only` and
  `BSD-2-Clause-FreeBSD` opens `BSD-2-Clause`,
* the 32 character identifier of a composed license,
* a whole license URL, from which the identifier is read,
* a DALICC identifier retired on 2023-04-24: it opens the record that replaced it, or,
  for the six retired test records nothing replaced, a page that says so.

An SPDX expression with an exception, `GPL-2.0-only WITH Classpath-exception-2.0`, is
not an identifier and the box refuses it. Either open the record under the DALICC
identifier, `GPL-2.0-only-with-Classpath-exception-2.0`, or ask
`GET /licenselibrary/spdx/<expression>`, which resolves the expression for you
([API.md](API.md)).

**By what you need to do.** That is the questionnaire, section 4.

**Unlisted licenses.** A license composed with the License Composer appears in no library
list, dropdown, autocomplete or search result, on the site or in the API. The only page
that lists it is the public profile of the account that published it, so keep the address
you were given. Every place that takes an identifier says so.

---

## 3. Read a license page

`/license-library/<id>` is the human readable license. It answers first and explains
after. From the top:

| Part | What it tells you |
|---|---|
| The title and the badges | the license name, a *Custom license* badge for a composed one, a *Test fixture* badge where that applies, a banner when a newer version exists or the publisher withdrew the license, and for a port, an edition or a variant a line naming the record it comes from |
| The answers under the title | three lines read from the statements below: *Commercial use* (allowed, not allowed, or the record does not say), *Share alike* (required or not required) and *Attribution* (required, meaning keep the copyright and license notices, or not required). An answer that comes from a default rule rather than from the record says *by default rule*; one that rests only on statements of library convention says *by library convention* |
| The operations row | bookmark, compare, add to the License Compatibility Checker, and the downloads as small quiet buttons |
| Section links | one link per section of the page, so a long record is one tap from any part |
| The canonical URI | the permanent address, with a **Copy** button |
| Who stands behind this license | on a composed license, the account that holds it and the account that composed it, by display name. Never an e-mail address |
| Permissions | one row per permitted action, with the duties that ride on it |
| Prohibitions | one row per prohibited action |
| License-wide duties | duties that apply whatever you do, share alike for instance |
| What applies by default | acts this license says nothing about, and what the reasoner then takes them to be. Each row names the legal source it rests on and is marked *by default rule (adopted)* or *by default rule (proposed)*, because it is not a statement of the license. None of it is legal advice |
| Further terms | what the license says about itself: whether it ends on a breach, the cure period, the governing law, whether a later version may be used |
| Clauses | the warranty and liability text, quoted from the license, never paraphrased |
| License text | the whole license in words, where the record carries one. A curated record carries none: it links the authoritative text instead |
| Info | the asset types, the region, the validity, where the legal text is, the license this description is published under (CC BY 4.0 for every curated record, linked by its title), the publisher, the creator, the licensor and the licensee, the SPDX identifier and the DALICC identifier, and the credit line to use when you reuse the record: "DALICC License Library, DALICC - Verein zur Förderung der Rechtssicherheit in der Datenbewirtschaftung, https://dalicc.net, CC BY 4.0". The license the record describes belongs to its publisher |
| Use this license | the sidecar, the RDF snippets, the attribution line and the badge (below) |
| The review box | when this record was last checked against the legal text, by whom, with what verdict, and every finding that still describes the record. A record written from the license text that nobody else has read says *Written from the license text by*, *Written on* and *Second review: not yet done* instead. When the record changed after the review, the box says *Record changed since this review: yes* with the version and the day, and findings a later version settled are folded under *Settled in version N* |
| History | every version of this record, newest first, with the date, the summary and the individual changes |
| Jurisdiction ports and editions | the records adapted from this license to another country's law, and the editions another body issued of it |
| Variants | the records that model the same legal text with one thing changed ([variant](#variant)): the or-later form, an exception that lifts one condition, a rider that adds one. Each is a license of its own, listed, searched and counted like any other |

**Ports and editions** ([port](#port), [edition](#edition)). The banner of a port names the license it adapts and the country
whose law it was adapted to. The Creative Commons ports are national versions of 2.0,
2.5 and 3.0: DALICC groups ports under the 4.0 International license of the same
elements, so the banner of *Creative Commons Attribution-NonCommercial 2.0 Chile* says
that it is a port of the 2.0 license, that it is grouped under 4.0, and that the legal
texts differ while the model states the same permissions, duties and prohibitions for
both. An edition says *Edition of* and names the license it reissues. The parent's page
lists them under *Jurisdiction ports and editions*, as members of the same family, not as
texts that say the same.

**Where each statement comes from** ([statement origin](#statement-origin)). Every
permission, prohibition and duty carries a small mark. *From the text* means the statement is the library's reading of a sentence of
the license; where the record keeps that sentence, the "?" beside it quotes it. *By library
convention* means the text is not explicit and the library states it by a convention it
applies to every license of the kind; the "?" names the convention. Under Prohibitions the
"?" starts with *Not permitted:* and the act, so a definition never reads as a grant. A
patent retaliation clause is not a ban on suing: it ends the patent license when a patent
claim is brought, so the page shows it under Further terms as *Patent license ends if you
sue*.

**What applies by default.** A license states what its text states, and most texts are
silent about most acts. What follows from that silence is a question of law, so DALICC
keeps it out of the record and in the dependency graph, where a rule says which act it is
about, what applies, in which territory and on the strength of which statute or
principle. The section lists what the core graph's rules supply for this license: today
that is one rule, which reads a license that says nothing about endorsement as granting
no right to use the licensor's name. A compatibility check draws the same conclusions and
says on every finding which side came from the text and which from a rule. Section 18
describes the seven further graphs that hold the rules proposed for the biggest markets.

**Downloads.** The operations row offers the model as JSON-LD, Turtle and RDF/XML, and
as **Text**, which is the license written out in words (section 19a). The same
serialisations come out of the API at `GET /licenselibrary/license/<id>`. Next to the row
there is a *Write this as a license text* link, which opens License-to-Text on this
license. It needs an account and says so when you are not signed in; the **Text**
download is the alternative without one.

The page ends with one sentence: nothing on it is legal advice, what a license means is
decided by its text, and you should ask a legal advisor before you rely on it.

**Use this license.** The page writes the statement out for you, so that a machine can
read your choice:

* a **JSON sidecar** to drop next to the work, naming the license URI, the title, the
  SPDX identifier, your asset and, only where the license really requires attribution,
  the attribution line. Fill in the two boxes above it and press
  **Download license.json**;
* the same statement as **RDF**, in Turtle and in JSON-LD;
* an **HTML attribution snippet**, shown only when attribution is required, so nobody
  pastes a credit line a permissive license never asked for;
* a **badge**, `/license-library/<id>/badge.svg`, with the markdown and HTML embed code
  next to it.

**Older versions.** A curated record is versioned. *View* in the History section opens
`/license-library/<id>/versions/<n>`, which renders the archived model read only, with
a banner and the downloads of that version. Asking for the current version number sends
you back to the license page, so there is one address per version.
`/license-library/changes` lists the recent changes across the whole library, filtered
by the kind of reason. Each change names the statement in words ("Prohibition: Promote"),
and a hand edit links the summary of its version on the record page, at
`/license-library/<id>#version-<n>`.

**Something wrong?** The review box of every curated page carries *Request a correction*
when you are signed in, which opens the structured form of section 20; without an account
the same place offers *Report an issue*, an e-mail link.

---

## 4. Search by what you need to do

`/license-search` asks a different question from the library list. There you look a
license up by its name; here you say what you need to do with the work, and the search
returns the licenses that let you do it.

1. **Asset types.** Creative work, dataset, software. All three are on; switch off what
   you are not licensing.
2. **Actions.** A three state switch per action: *permitted*, *does not matter*,
   *prohibited*. Every switch opens at *does not matter* on purpose, because a search
   that demands eleven permissions at once returns nothing.
3. **Duties.** Two state switches under the action they belong to: attribution, notice,
   source code, rename, modification notice, compliant license.
4. **License wide duties.** Share alike.

Press **Search**. Results come back grouped the way the library list is grouped, parents
with their ports underneath.

**Two rules worth knowing.**

* *Share Alike* and *Change License* exclude each other. The page disables one when you
  choose the other, and a submission that contains both is refused with an explanation
  rather than silently corrected.
* Five nested questions (Display, Present, Modified Works, Derivative Works, Promote)
  have no facet in the search API. The page still asks them, but it uses the answers to
  annotate the results rather than to filter them: for the first 25 results it adds a
  note such as "This license does not prohibit Display". In the composer the same
  questions are real, and what you answer there goes into the model.

---

## 5. Compare licenses

`/license-comparator?ids=MIT,Apache-2.0,GPL-3.0-only` puts the licenses side by side:
the question tree down the first column, one column per license, and a mark per cell
(granted or required, prohibited, not applicable). A row the licenses disagree on is
flagged, so the differences are the thing you see first.

* Add a license by name with the autocomplete, or by identifier with **Add by id**,
  which is how an unlisted license joins a comparison. A name is read the way the License Compatibility Checker
  reads it (section 6).
* An identifier the library does not hold gets no column; the page says it was left out.
* The first column and the header stay put while you scroll sideways, and the whole
  table prints.
* The comparator also opens as a dialog from the License Compatibility Checker, over the bundle you
  have there.
* Every mark is a statement of the license text. Where a license says nothing the row is
  *not applicable*, and a compatibility check answers it by default rule instead; the
  note under the legend says so and links the dependency graph.

---

## 6. Check whether licenses fit together

The License Compatibility Checker, at `/license-compatibility-checker`, answers the
question that sends most people to DALICC: may I combine these works, and what may I
publish the result under? It has three steps. Until 2026-09-25 it was called the License
Mixer; a link to `/license-mixer` still works and opens the same bundle here.

**1. Define your license bundle.** Add licenses by name with the autocomplete, or by
identifier with *Add to bundle by id* (the way in for an unlisted license). A typed name
is matched, in this order, against the identifier, the title, the SPDX identifier (a
deprecated one such as `GPL-3.0+` included), the other names a record carries ("MIT
license" is The MIT License) and only then the start of a title; a license found by the
start of its title is added with a sentence saying which one it was, so you can take it
out again. Your bundle is listed with an expandable summary per license (its permissions,
prohibitions, license-wide duties and the duties attached to permissions) and a link to
remove one. An identifier the library does not hold is marked "No license with this
identifier is in the library.", and the bundle is not checked until it is removed or
corrected; an entry of the address that is not an identifier at all is named and left
out.

**2. Check the compatibility of your bundle.** Press **Check compatibility**, or open a
link to a bundle, which runs the check for you. The reasoner reports every pair of
statements that cannot both hold, and the License Compatibility Checker sorts each one into one of three kinds:

* a **conflict** ([glossary](#conflict)): no combined work can meet both statements. One license requires what
  the other prohibits, or two licenses each require the whole work to stay under
  themselves (GPL-2.0-only and GPL-3.0-only, the ODbL and CC BY-SA 4.0) and no "or later"
  option or compatibility clause leads from one to the other;
* a **restriction** ([glossary](#restriction)): one license permits an act the other prohibits, so the combined work
  may not do it. "The MIT License permits Change license; GNU General Public License 3
  prohibits it, so the combined work may not change its license. The permissive work can
  go into the copyleft one, not the other way round." That is not a reason not to combine
  them;
* a finding **about one license alone**: a license that contradicts itself. It is shown,
  and it does not decide the verdict.

The verdict names the worst kind: **Cannot be combined** (at least one conflict),
**Can be combined with restrictions** (only restrictions) or **No conflict found among
the statements DALICC models** (nothing found). A bundle of one license is told that it
has nothing to be combined with. Every finding says whether it is **direct** (both
statements are in the texts) or **derived** (it follows through the dependency graph,
and the tooltip names the step, for example "Grant use is the same act as Sublicense"),
and **by default rule** where one side is not a statement of a license text but one a
default rule of the graph supplied for an act that license says nothing about. Nothing in
any finding is legal advice. A pair the reasoner reaches twice is listed once.

Under every verdict, **What you must do** lists the duties of the combined work: every
license-wide duty and every duty a permission carries, once each, with the licenses that
impose it ("Attribution (The MIT License, Apache License, Version 2.0)"). **What the
check cannot see** says where to stop trusting it: compatibility no license states,
clauses the vocabulary cannot express (a ban on selling or on production use), and the
license texts themselves. Read the texts before you combine the works.

Compatibility a license grants by name, in one direction, is seen where its record
states it: CC BY-SA 4.0 lets an adaptation go under GPL-3.0, the LGPL lets its code be
relicensed under the GPL, and AGPL-3.0 and GPL-3.0 allow each other. Two licenses that
each keep the whole work under themselves then combine, with the restriction "The
combined work has to be released under GPL-3.0" (or under either one, when each names
the other). With a target license, the named direction has to lead to the target:
GPL-3.0 code cannot be released under CC BY-SA 4.0.

**3. Check and download your license statement.** Unless the bundle cannot be combined
you may name a **target license**: the license you want to publish the combined work
under. It comes from the dropdown of curated licenses, or from the field next to it that
takes the identifier of an unlisted one. The step says, for every license of the bundle,
whether it can be released under the target, gives the verdict over the bundle and the
target together, names a license that is not written for an asset type the target
covers ("The MIT License is not written for Dataset, which Apache License, Version 2.0
covers.") as a note, and **Download statement** gives you `statements.txt` with the
verdict, what you must do and what the check cannot see, to keep with the work.

**Choosing the rules.** The *Dependency graph* select at the top decides which axioms and
which default rules the reasoner uses: the core graphs for everybody, your own as well
once you are signed in
(section 18). The choice travels in the address (`?graph=`) and is printed in
`statements.txt`, so a downloaded statement always says what it was derived with. How a
derived conflict comes about is walked through at `/reasoning` (section 11).

**Sharing and losing work.** The bundle lives in the address
(`/license-compatibility-checker?ids=MIT,Apache-2.0`), so a link carries it to a colleague, and opening
the link checks the bundle again. The browser also remembers the last bundle, so a
detour to a license page does not lose it.

**When something is down.** If the reasoner cannot be reached the page says so inside
the step and keeps your bundle; it does not become an error page. If the license store is
unreachable the tools fall back to a copy of the records and say so.

---

## 7. Compose a license

`/license-composer` writes a license of your own. It is the same question tree as the
search, read the other way round: there you filter, here you decide. If you already have
the text of a license, Text-to-License reads it and fills this form in for you, and you
review the proposal before anything is saved (section 19).

**Start from a library license.** The first field of the form takes the name of a
curated record, and *Load* fills the whole form in from it: every permission, every
prohibition, every duty where it hangs, the disclaimer texts and the provenance fields.
Type a name and pick it from the list, or give a DALICC identifier such as `Apache-2.0`;
pressing Enter in the field loads it too, and nothing else has to be filled in first.
Two things are not copied. The title stays empty, because what you are about to write is
a variant and needs a name of its own. The license your license is provided under stays
the one the record states for itself, CC BY 4.0 on every DALICC record: that is the
license of the model document you are adapting, not of the terms it describes. Loading
replaces everything you have typed so far, writes nothing anywhere, and needs no account.

1. **Provenance information.** Title, creator, licensor, licensee, validity (dates, a
   number of months, or unlimited), region and country, and the license your license is
   itself provided under. Below those, six fields for a license that already exists
   somewhere: who published it, its SPDX identifier, the version of the license itself,
   the address of its text, where this model comes from, and the other names it is known
   under, one per line. All six may stay empty. They are stored the way the curated
   records store them, so a model you write here reads back like one of ours.
2. **Permissions and duties.** Per action: permitted (a tick), not addressed (a dash:
   the license says nothing about the action) or prohibited (a cross), with
   the duties that ride on each permission. A duty always hangs on a permission, never on
   a prohibition.
3. **License wide duties.** Share alike and the rest.
4. **Further statements from the reading.** What the questions above have no switch for:
   a duty under a permission with no box for it, an action with no question of its own,
   and a duty the questions have stopped offering, which is how a draft saved while
   there was still a box for it keeps the statement.
   Each gets a row with the quote it came from, the permission it hangs on and a box
   that keeps it. They are part of the license, so the consistency check includes them
   and so does everything you save, download or publish. Clear the box on a row you
   disagree with and it is gone. The expert view below shows the same statements as
   ordinary rows.
5. **Disclaimer.** Warranty disclaimer, liability limitation, any additional clauses.
6. **License text.** The license in words, kept with the license itself. *Write this as
   a license text* sends the form as it stands and brings the text back into the field
   on this page, so you can correct it before anybody reads it. That button needs an
   account, unless the installation opens License-to-Text to everybody; typing or
   pasting your own text into the field needs none. The field is optional and holds up
   to 60,000 characters. Whatever is in it when you check, download, save or publish is
   stored with the license as `dalicc:licenseText`; the license page then shows it under
   *License text*, and `GET /licenselibrary/license/<id>?format=text` answers with it.
   Two more buttons do their work in your browser and ask DALICC for nothing:
   *Download as text* saves the field as a `.txt` file named after your title, and
   *Remove text* empties it after asking whether you mean it. Writing a text publishes nothing, and the names you
   entered are left out of what is sent (section 19a).

### Expert mode

Above the questions there is a switch with two settings: *Questions* and *Expert*. It
decides only how you state your terms. The title, the asset types, the validity, the
disclaimer texts and the license text are the same fields in both, and switching keeps
everything you have entered.

The expert view shows your whole license as a tree instead of a fixed set of questions:

* **Permissions.** One row per permission, each with the duties that ride on it. *Add
  duty* on a row adds a nested duty under that permission.
* **Prohibitions.** One row per prohibition.
* **Duties of the license.** One row per duty that applies to the license as a whole
  rather than to one permission.

The *Promotion specification*, which the questions ask for under *Promote*, has a field
of its own at the end of the *Disclaimer* section in the expert view.

Each row has a search box. Type a few letters and pick the action from the list: it
holds every term of the DALICC vocabulary that may be used at that level, and the
definition appears under the row once you have chosen one. *Add permission*, *Add
prohibition* and *Add duty* add a row at the end of a block, and *Remove* takes one
away. Enter in a row adds the next row of the same kind under it instead of sending the
form. After *Remove* the cursor moves to the row that took its place, or to the button
that adds one when the block is empty, and every *Remove* and *Add duty* button names
the row it belongs to for a screen reader ("Remove permission Distribute").

**Nothing is hidden here**, which is why the view exists. A license loaded from the
library, or read out of a text by Text-to-License, often states things the questions
have no switch for, and in the question view those sit in *Further statements from the
reading*. Switch to the expert view and they are ordinary rows you can change like any
other; switch back and whatever the questions cannot hold returns to that panel. Your
license is the same license either way.

Two rows the tree does not offer, because a DALICC license cannot state them: a duty
under a prohibition, and a duty under another duty. A prohibited act never happens, so a
duty conditioned on it could never apply.

A row with no action yet, an action DALICC does not know, or a duty term used as a
permission stops the buttons: the list next to the editor names the row, and nothing is
checked, saved or published until you fix it. Without JavaScript the tree is shown as
one text field holding the same statements as JSON, and every button still works.

The switch remembers itself in your browser, so the composer opens the way you left it,
including when Text-to-License hands a reading over and when you re-open a draft.
`/license-composer?mode=expert` opens the expert view straight away.

### Checking, saving and publishing

Three buttons, and a fourth when you are signed in:

| Button | What it does |
|---|---|
| **Check consistency** | runs the consistency check and lists the contradictions. Nothing is written |
| **Download RDF** | gives you the license as Turtle, JSON-LD or RDF/XML, without publishing anything |
| **Save draft** (signed in) | keeps it privately under *My licenses*, where you can come back to it |
| **Publish** | checks consistency, then mints the license at its permanent address |

**Three formats.** *Download RDF* has three buttons: *Turtle* saves a `.ttl` file,
*JSON-LD* a `.jsonld` file and *RDF/XML* a `.rdf` file. All three hold the same model,
the one the check and *Publish* would use, and the JSON-LD uses the same context as the
JSON-LD downloads of the license library. The file is named after your title, for
example `my-data-licence.ttl`, or after the draft when you are editing one.

**Continue from a downloaded model.** Under *Start from a library license*, choose a
file you downloaded earlier (`.ttl`, `.jsonld`, `.json`, `.rdf` or `.xml`, up to 2 MB)
and press *Load file*. The form is filled in with everything the file holds, title
included, in the view you are in, and the note beside the control says "Loaded *title*
from *file name*." A file that is not RDF, or holds no license or more than one, is
refused there in a sentence and your form stays as it was. A term DALICC does not know
is named in the note and left out; the rest is loaded. The file is read on the server
and forgotten: nothing is stored, and no account is needed.

Publishing also asks you to tick one box, whether or not you are signed in: the license
model and the creator name you typed go public permanently under CC BY 4.0, and that is
not something to do by mistake. Press *Publish* without it and nothing is written
([privacy notice](https://dalicc.net/privacy)). The other three buttons never ask,
because none of them publishes anything.

**Where the answer appears.** A button answers where it is: *Load* at the top of the
form, *Load file* under its own control, *Write this as a license text* inside the *License text* section, and the four
buttons above under *My resulting license*. When a field needs correcting, the message
is on the field itself and the block next to the button lists those fields as links that
take you there. The page scrolls the message into view and puts the keyboard focus on it, and a refusal re-renders
the form with your values intact.

**When the license store does not answer.** *Save draft* and *Publish* then come back to
the same page with every answer still in the form, the draft you were editing and the
ticked box included, and a message under the buttons headed *Nothing was saved* or
*Nothing was published*. Nothing was written: no draft appears under *My licenses*.
Press *Download RDF* to keep a copy on your computer and try again in a few minutes.
A name *Load* cannot find is answered at the top of the form under *Nothing was
loaded*.

**What a contradiction looks like.** The *Consistency* panel lists every contradiction,
naming the two statements of your license that clash, for example `Permission: Distribute`
and `Prohibition: Distribute`. Where the dependency graph was needed to find the clash,
the step that connects them is printed underneath, for example "Distribute is included in
Use." The panel keeps up as you edit, so you can watch a contradiction disappear. The
select next to *Check consistency* decides which graph it reasons with, and what counts
as a contradiction is explained on `/reasoning` (section 11).

**What you get.** A 32 character identifier and a permanent address. The license is
**unlisted**: no library list, no search result, no dropdown; only your public profile
lists what you published. Keep the address. If you were
signed in you own it, can share it and can version it (section 17); composed anonymously
it has no owner and nobody can claim it later.

Composing without an account can be switched off for an installation: an administrator
sets that, and the composer then asks you to sign in
([DEPLOYMENT.md](DEPLOYMENT.md#45-accounts-sessions-and-the-account-database)). Where
the installation is configured for it, the publish step also carries a reCAPTCHA.

---

## 8. Check a repository's dependencies

The GitHub License Compatibility Checker is at `/github-license-compatibility-checker`.
This is the License Compatibility Checker applied to a repository: the licenses of its
dependencies are checked against the license you choose. It takes a GitHub repository, as `owner/name` (for example
`psf/requests`) or as its URL (`https://github.com/psf/requests`), and reports

* the repository and its main language,
* every dependency with the license the package index reports for it, and the DALICC
  record it resolves to,
* the compatibility verdict over all of those licenses together, in the same rendering
  the License Compatibility Checker uses: conflicts, restrictions, what you must do and what the check cannot
  see (section 6).

**Your target license.** Under the repository field you may name the license you would
publish the combined work under, either from the dropdown or by typing the identifier of
an unlisted one. The compatibility check then runs over the dependency licenses and that
license together, which is the question the License Compatibility Checker asks, and the result is
reported in two parts: *Between the dependencies*, and *With your target license* for the
conflicts the target itself is one side of. A target counts as a license of its own, so a
repository with a single recognised dependency license still has two licenses to compare.
Leave the field empty and the page checks the dependencies against each other alone.

The lookup reads a public package index, which needs an access key that an administrator
configures. Without one the page says the checker is switched off on this installation
and the button is disabled; the API answers `503` and names the setting.

A link to the page with `?repo=owner/name` opens it with the field filled and the check
run, which is what the *Check* tile on the home page submits. Until 2026-09-25 the page
was called the GitHub License Checker; `/github-license-checker` still works and leads
here.

---

## 9. My Bookmarks

`/bookmarks` is a shortlist of licenses, and it is in the Licenses menu. **Add bookmark**
on a license page or a result card puts a license on the list, **Remove bookmark** takes
it off again, and the page shows you what is on it. The old "My Dashboard" address still
works.

The list lives in your browser only. Nothing is sent to the server, nothing is tied to an
account, and clearing your browser data clears it. **Export as JSON** writes the list to a
file and **Import JSON** reads one back, which is how it moves to another machine.

"My licenses" is a different thing: those are the licenses you own on the platform, and
they need an account. See [Your licenses](#17-your-licenses-roles-sharing-and-versions).

---

## 10. The DALICC vocabulary

`/ns` is the vocabulary: every term DALICC uses to model a license, with its definition
and the term it derives from. Term addresses are fragments, so
`https://dalicc.net/ns#promote` is the term itself, and `/ns/<term>` is a convenience
redirect to it.

The page serves the vocabulary as data too: ask for Turtle, RDF/XML or JSON-LD (with an
`Accept` header or `?format=`) and you get the authored file, comments included. The
vocabulary is versioned exactly like a license: `/ns/versions`, `/ns/versions/<n>` and
`/ns/changelog`, with a history section on the page.

The vocabulary is the single source of truth for the terms. Everything that offers you a
list of actions (the composer, the search, the dependency graph editor, the translation
assistant) reads it, so a term defined there shows up everywhere. How it is written and
extended is in [DATA.md](DATA.md).

---

**Accounts.** The six sections that follow are about who DALICC thinks you are: how an
account comes about, what it may do, and how a session and an API token are protected.

## 11. Concepts

**Account.** An e-mail address, a display name, a password and a role. Accounts come
**by invitation** unless the administrators have opened sign-up; then the sign-up page,
and where one is set up an identity provider, create accounts as well. Nothing creates
an account without an invitation, the sign-up page or an administrator behind it, and
every page that tells a visitor how to get one says which of these the site offers.

**Roles.** Two, deliberately coarse. A `member` owns the licenses they created, shares
them, and manages their own API tokens and profile. An `admin` manages people,
invitations, settings and the audit log, and may act on any license. Section 12 has the
whole list.

**License roles** are a second, independent axis: `owner`, `editor` and `viewer` on each
license, whatever your role on the platform. Section 17 has the matrix and the life of a
license.

**Anonymous use stays possible.** Searching, comparing, mixing and, unless the
installation says otherwise, composing a license need no account.

**No e-mail address is ever shown publicly.** A license page shows the owner's display
name (or "unnamed") and the profile address `https://dalicc.net/users/{user_id}`. Your
e-mail address is visible only to you and to administrators, and no public page shows
one.

**How reasoning works.** Every answer DALICC gives about conflicts rests on two things.
The first is the rules of a license: each rule is a permission, a prohibition or a duty
over one named action. The second is a dependency graph, which says how those actions
relate to each other. `/reasoning` explains both without jargon, in five steps with a
picture: what a rule is, what the four kinds of statement in a graph mean, and how the
checker tells a direct conflict from one derived through the graph. Two tools ask the
question, the compatibility check of the License Compatibility Checker (section 6) and the consistency
check of the License Composer (section 7), and both follow the graph they were given.
A graph is one reading of how the actions relate: another legal reading, another
jurisdiction or the practice of one organisation can call for a graph of its own
(section 18).

**Where your pages are.** Once you are signed in, the last entry of the main menu is
**Account**, and it holds the six things you open from anywhere: Account settings, Inbox
with its unread count, My licenses, My dependency graphs, the Admin area if you are an
administrator, and Log out. Everything else is one click further in, in the column that
runs down the left of every page behind the login, under *You*, *Your work* and, for an
administrator, *Administration*. The page you are reading is marked in the column. On a
narrow screen the column becomes an **Account menu** button above the page.

---


## 12. Who may do what

| Capability | anonymous | member | admin |
|---|:--:|:--:|:--:|
| Browse the library, compare, mix | yes | yes | yes |
| Compose a license (unless the installation requires an account) | yes | yes | yes |
| Own a license, publish a new version of it | no | yes | yes |
| Invite a collaborator to one of their own licenses | no | when the installation allows it | yes |
| Create and revoke personal API tokens | no | yes | yes |
| Invite a member or an administrator | no | no | yes |
| Change a role, deactivate an account | no | no | yes |
| Reset another person's password | no | no | yes |
| Read the audit log and the settings page | no | no | yes |
| Act on any license, withdraw it | no | no | yes |

An administrator sees the same table at `/admin/settings`.

Nobody, administrators included, can read an existing password: only a one-way hash of
it is kept. An administrator can *replace* a password (with a temporary one that must be
changed at the next login) or create a reset link, and both are shown exactly once.

Every value DALICC shows once, a temporary password, a reset link, an invitation link or
a new API token, stands in a box with a **Copy** button beside it. Pressing it puts the
value on the clipboard and the button reads *Copied* for a moment. If the browser will
not let it copy, the button says *Press Ctrl+C* instead, and the value is selectable text
either way. Copy it before you leave the page: none of these is ever shown again.

### The name you publish under

Your account has one name, and it is the only thing about you that a published license
shows. Every license you publish carries it as the publisher, so a reader can tell who
stands behind the document. Three rules keep that name yours.

* **One account, one name.** Two accounts cannot publish under the same name. The
  comparison ignores upper and lower case, extra spaces and the way the letters are
  encoded, so "Ada Lovelace" and "ada  lovelace" are the same name.
* **An address can only be your own.** A name with an `@` in it is read as an e-mail
  address, and the only address you may use as your name is the one you log in with.
  Nobody can put somebody else's address, or the address of somebody who has just been
  invited, on a license page.
* **A name a published license already carries belongs to its publisher.** Some published
  licenses have no account behind them, so their publisher names are held for everybody.
  If one of them is yours, ask an administrator to release it to your account.

You set the name on `/account`, an administrator can change it for you, and the
invitation form asks for it when the account is set up. In each of those places a name
that is not free is refused, and the message says which of the three rules it ran into.
Renaming yourself changes nothing that is already published: a license keeps the name it
was published with.

### Your public profile

`/account` shows a **public profile address**, `https://dalicc.net/users/<your id>`, and
it is a link. That address is how every license you publish names you, so it is in
documents other people hold, and it opens a page anybody can read. The page shows your
name, the month your account was created in, and the licenses and dependency graphs you
have published, each one linked. It shows nothing else: not your e-mail address, not
when you last logged in, not your role, and none of your drafts. A license somebody
shared with you belongs on their profile, not on yours.

The same address answers as data as well. Ask it with `Accept: text/turtle`,
`application/ld+json` or `application/rdf+xml`, or add `?format=ttl`, `?format=json-ld`
or `?format=rdf-xml`, and you get a small document: you as a `foaf:Agent` with your
`foaf:name`, and one statement per published license, written exactly as the license
document writes it. An identifier no account has is a `404`.

If you delete your account the address keeps working, because the licenses that name it
are still published. It then shows the neutral label your row keeps, and nothing about
you at all.

---


## 13. Invitations

How you get an account depends on how the installation is set up. On dalicc.net, and
wherever nothing else was chosen, accounts are given out **by invitation**: ask an
administrator through the contact form, and follow the steps below. An installation
can also open **sign-up**. Its login page then has a *Create an account* button, and
the steps are in [Signing up yourself](#signing-up-yourself) further down.

An invitation is a random link; only a hash of it is stored. The link itself exists in
exactly one place: the mail that was sent, or the line the page showed the inviter once.

1. `/admin/invitations`: address plus role, one form.
2. Where the installation can send mail, the invitee gets one. Where it cannot, the page
   shows the link and says so; pass it on through a channel you trust.
3. The invitee opens `/invite/<token>`, sees who invited them and in which role, and
   sets a name and a password. The account is created and they are logged straight in.
   The form also asks them to confirm that they have read the
   [privacy notice](https://dalicc.net/privacy) and that the name they choose is shown
   on every license they publish. Without that tick no account is created.
4. The invitation is marked accepted and the link stops working.

The name asked for in step 3 follows the rules in section 12: it has to be free. A name
that belongs to another account, or to the publisher of a license that is not yours, is
refused with the reason. The invitation link keeps working after a refusal, so you can
open it again and choose another name.

An invitation expires after a week by default (an administrator sets the period) and can
be used once. An administrator can **withdraw** a pending one, or **create a new link**
for the same address, which withdraws the old one so only the newest mail works.

An invitation for an address that *already* has an account is legitimate and useful: it
is how a deactivated account is invited back, and accepting it reactivates the account
and sets a new password. An invitation never lowers an existing account's role.

### Signing up yourself

Where an administrator has opened sign-up, `/register` asks for the same things an
invitation does: the name you publish under (the rules of section 12 apply), your
address, a password (section 14) and the tick that confirms you have read the privacy
notice. What happens next depends on what the administrators chose, and the page lists
it next to the form:

* **Confirming your address.** A link goes to the address you gave. Open it and press
  *Confirm my address*, and you are signed in. The link works once and for a day; if it
  runs out, log in with your address and password and a new one is sent. An account whose
  address is never confirmed is deleted a week after its last link runs out.
* **Waiting for approval.** You can sign in, compose and save drafts at once, but you
  cannot publish until an administrator has approved the account. You get a mail when it
  is approved, and also when it is not, in which case the account and its drafts are
  deleted.
* **A check against automatic sign-ups** may sit on the form. It is the same check as on
  the composer, the form says what it sends where, and the privacy notice says more.
* **Only some addresses** may be allowed, for example those of the member institutions.
  The form says which.

If the address you type already has an account, the page answers as if it did not and
the owner of the address gets a mail saying that somebody tried, so the form does not
tell a stranger who has an account here.

### Signing in with your organisation's account

An installation can also offer **Sign in with the identity provider** on the login page,
and **Sign up with the identity provider** on the sign-up page. The button takes you to your organisation's sign-in page and
back. If DALICC already knows your address, you are signed in to that account, and from
then on it is recognised even if your address changes at your organisation. If it does
not, and sign-up is open, one more page asks for the name you publish under and the
privacy notice tick; there is no confirmation mail, because your organisation has
already confirmed the address, but an administrator may still have to approve the
account. Where sign-up is closed, the provider signs in existing members only.

When the provider is the only way in, the password form refuses members and says so.
An account created through the provider has no password; to delete it, sign in through
your organisation and confirm on `/account/delete` within 15 minutes (see
[Your data](#22-your-data)). Deleting your account also removes the link between it and
your organisation's identifier, and the account export lists that link under
`identity_provider`.

---


## 14. Passwords

* A password is stored only as a strong one-way hash, never as the password itself.
* At least 12 characters; the address, the local part of the address and the person's
  own name are refused, as are strings built from fewer than five distinct characters.
  Length is the only thing that really matters, so a short sentence is a good password.
* A password is never logged, never returned, never shown in the interface and never
  put in an audit entry.
* A wrong password and an unknown address produce the same message and take the same
  amount of time.
* Login is rate limited to 10 attempts per minute per client address.
* Changing or resetting a password ends every other session of that account.

**Forgotten password.** `/forgot-password` always answers the same way, whether or not
the address is known. Where the installation can send mail, a one-shot link valid for a
day is sent; creating a new link invalidates the previous one. Where it cannot, the page
says to contact an administrator, who can produce the same link from the account page.

---


## 15. Sessions, cookies and staying signed in

Signing in gives your browser two cookies and nothing else. There is no session table on
the server, so nothing about you is kept between one request and the next. One cookie
says which account you are signed in as and runs out after fourteen days by default; the
other carries a random value that each form you submit has to send back, so that another
website cannot make your browser act in your name. Neither can be read by JavaScript, and
a browser sends them to DALICC and to nowhere else. How long a session lasts, and whether
the cookies are restricted to secure connections, is something an administrator sets.

**Signing out everywhere.** *Log out everywhere* on your account page ends every session
you have, on every device, at once. The same happens by itself when you change your
password, when a password reset completes, when an administrator sets a temporary
password for you, and when an account is switched off. *Log out of this device* on the
same page, or **Log out** in the menu, ends only the session on the device you are using.

**"Reload the page and try again."** A form whose protection value no longer matches is
refused with that message. It usually means the page sat open for a very long time, or
that you signed in again in another tab. Nothing you typed was sent on; reload the page
and submit it once more.

**Where you are sent.** Open a page that needs an account while you are signed out and
you land on the sign-in form; once you are in, you are taken on to the page you asked
for. Only addresses on this site are accepted there, so the form cannot be used to send
you somewhere else. If an administrator gave you a temporary password, every account
page sends you to the password form until you have chosen one of your own.

How the cookies are signed and how form protection is implemented is in
[SECURITY.md](SECURITY.md#2-authentication-and-authorisation).

---


## 16. API tokens and calling the API

A token looks like `dalicc_` followed by 40 random letters and digits. Only a hash of it
is stored; the first eight characters are kept so that the list at `/account/tokens` can
tell your tokens apart. The token itself is shown once, right after it is created, with a
*Copy* button next to it, and the column *Token (first characters)* in the list shows
only those first characters, so a token you did not copy cannot be read back and has to
be revoked and replaced. Revoking is immediate, and a token stops working the moment its
account is deactivated.

Send the token in the `Authorization` header, as `Bearer dalicc_...`. Without one, or
with a revoked one, the answer is `401` and its body says what to send.

Requests made with a token are counted against your account and written to a request log
that keeps the account, the token's row, the path without its query, the method, the
status and the time. The log is trimmed to the last seven days, and the daily figures
that outlive it hold no personal reference
([privacy notice](https://dalicc.net/privacy)).

Every successful call updates the "last used" time shown beside the token. The endpoints
that take a token are the ones that act for you: composing a license
(`POST /licenselibrary/composer`), listing your own (`GET /licenselibrary/mine`),
withdrawing one of yours, your dependency graphs and Text-to-License. Everything that
only searches, reads or reasons needs no token at all. The request and response shapes
are in [API.md](API.md).

---

**Your own work.** Everything you make with an account: licenses, dependency graphs,
translations, and the conversations with the curators about them.

## 17. Your licenses: roles, sharing and versions

A license and an account are two different things. The account roles above
(`admin`, `member`) say what somebody may do with DALICC; the **license roles** say what
they may do with one particular license. They are independent: a member owns what they
composed, and an administrator may act on anything.

### The three roles

| Role | May |
|---|---|
| `owner` | everything: edit the draft, publish it, share it, transfer it, start a new version, withdraw it |
| `editor` | view it, change the draft, start a new version of a published one |
| `viewer` | view it, including a private draft |
| (`admin`) | everything, on any license, whoever owns it |

The split is deliberate: the creator formulates the terms and the owner approves them.
That is why an editor cannot publish and cannot share, and why publishing a version
somebody else drafted is always the owner's act.

Exactly one account owns a license and everybody else holds a role on it. A transfer
moves ownership and leaves the previous owner behind as an editor, so nobody is locked
out of work they did.

### The life of a license

**Draft.** Private to you and the people you shared it with. It has no public page and
appears in no list, no search result and no dereference. Saving again replaces it; the
identifier never changes. Every save is kept as a **revision**, so replacing it never
loses the wording it had before (see *Revisions* below).

**Published.** The license gets its permanent address,
`https://dalicc.net/licenselibrary/<id>`, and is **unlisted**: it is in no library list
and no search result, and only your public profile lists it, so keep the address. The document names you as its owner by your profile
address, never by your e-mail address. It cannot be edited afterwards.

**New version.** "Edit" on a published license copies it into a fresh draft with a new
identifier. When you publish that draft, the previous version is marked **superseded**
and the two point at each other. Both addresses keep working forever, which is the
point: a contract that names version 1 can still be read years later.

**Superseded** ([glossary](#superseded)). A newer version replaces this one. The page of the old version says *A
newer version exists*, links the new one and says that rights already granted under the
old version are not affected by the new one.

**Withdrawn** ([glossary](#withdrawn)). The publisher no longer offers the license for new uses. The License
owner or an administrator sets it with **Withdraw this license** on the manage page,
with an optional reason. The page says *Withdrawn by its publisher*, gives the date and
says that whether rights already granted continue is decided by the license's own terms,
which stay readable. Nothing is deleted. Naming a successor in the same form makes the
license superseded rather than withdrawn.

The two states share one flag in the data, `owl:deprecated true`, and the address of
the form is still `/my/licenses/<id>/deprecate`, so older links and API clients keep
working; docs/DATA.md has the mapping.

**License owner** ([glossary](#license-owner)). The record page names the account that holds a composed license as
its *License owner*: the account that publishes and maintains it on DALICC. DALICC does
not check that this account holds the rights it licenses, and it does not review the
terms.

### Revisions: every save is kept

A draft is rewritten in place on every save, so DALICC takes a snapshot first. The
manage page of a license lists them, newest first:

| Column | What it says |
|---|---|
| Revision | `r1`, `r2`, `r3` ... within this license. The number never repeats. |
| Saved | when it was written, in UTC |
| By | the display name of the person who saved it, and a badge when that was an administrator |
| What it was | `draft` (an ordinary save), `publish` (the state a version was published in) or `restore` |

Three things can be done with one:

* **View** renders it read only, on the same page the public license page uses, with a
  banner saying which revision it is and that it is not published.
* **Turtle** downloads it exactly as it was saved.
* **Restore as current draft** copies it back into the draft. It really is a copy: the
  revision you restored from stays in the list, and the state it replaced is appended as
  a new revision first, so a restore can itself be undone. Nothing is ever deleted.

An owner, an editor and an administrator can see the revision list; a viewer cannot.

Over the API the same list is
`GET /licenselibrary/mine/{id}/revisions` (see [API.md](API.md)).

### When an administrator edits your license

An administrator may open any license in the composer, save drafts, publish new versions
and withdraw them. That is how the DALICC team can correct a license it is asked about
without taking it over. It is never silent: the revision is attributed to them with a
badge in the list, the manage page shows the owner a notice naming who edited it and
when, and the audit log records the publish with the administrator as the actor. The
owner can restore any earlier revision, so an edit they disagree with is undone in one
step.

Ownership does not change, and the published document still names the owner as its
owner. An administrator editing a license is an edit, not a transfer.

### A walkthrough

1. Log in and open **License Composer** (or *My licenses* then *New license*).
2. Fill the form in and press **Save draft**. You land on the manage page of your
   license, `/my/licenses/<id>`.
3. **Share** it: enter a colleague's address and pick *Editor* or *Viewer*. If they have
   an account they see it at once under *Shared with you*; if not, an invitation is
   created and, when no mail can be sent, the link is shown to you once to pass on.
4. **Edit draft** re-opens the composer with everything where you left it.
5. Tick the box that publishes the license model and the creator name permanently
   under CC BY 4.0, the same box the composer shows, and press **Publish**. Without the
   tick nothing is published. You land on the public page.
6. Later, press **Create new version**, change what must change, and publish again.
   Version 1 keeps its address and gains a banner pointing at version 2.
7. If terms must be withdrawn without a successor, press **Withdraw this license**,
   optionally with a reason.

**Actions that ask first.** Removing a person, transferring ownership and withdrawing a
license each ask a question before anything happens, saying what the action does and
what stops working. Answer *Cancel* and nothing is sent. Revoking an API token asks the
same way. Without JavaScript the button acts at once.

### Where to find things

`/my/licenses` lists everything you own and everything shared with you, with status,
version and your role; `/my/licenses/{id}` is the manage page, with the details, the
version timeline, the people and every action you are allowed. The answer to a button
on that page is shown in the section of the button, *People* for sharing, *Revisions*
for a restore, and the page opens there. Two more addresses are
worth keeping: `/license-composer?draft={id}` opens the composer with that draft loaded,
and `/my/licenses/{id}/revisions/{r}` shows one saved state read only. Once published,
the license is at `/license-library/{id}`.

These lists, the revision and people tables, and the other tables of records on the
site sort by a column when you press its heading (press again to reverse the order); the
browser remembers the last sort of each table for your next visit.

Over the API, the same licenses are `GET /licenselibrary/mine`, and
`POST /licenselibrary/composer` composes one with a token
(see [API.md](API.md#24-post-licenselibrarycomposer)).

Every one of these acts is written to the record an administrator can read, and no entry
there ever holds a password, a token or the text of a license
([ADMINISTRATION.md](ADMINISTRATION.md#10-the-audit-log)).

---


## 18. Dependency graphs

A dependency graph is what the compatibility checker reasons **with**. It carries two
kinds of statement. An **axiom** says which actions include, imply, equal or contradict
which other actions. A **default rule** ([glossary](#default-rule)) says what applies to an action a license is
silent about: which action, what applies, in which territory, and which statute or
principle it rests on. Change either and every answer the service gives changes, which
is why a graph is an owned, versioned object exactly like a license.

Nothing a default rule states is legal advice. It is the library's reading of a legal
default, named with the source it rests on, and a rule marked *Proposed* is a question
for a legal reviewer rather than an answer ([adopted](#adopted), [proposed](#proposed)).

Two pages carry that name, one for reading and one for writing. The **Dependency Graph
Viewer** at `/dependency-graph` shows a graph in full: every statement grouped by its
relation, the diagram, the Turtle download, the same data as JSON and the version
history. It does that for the core graphs and for any graph you are allowed to see.
Every graph is complete: it holds every axiom and every rule a check under it reads. The
page of a jurisdiction graph, and the Viewer when one is chosen, therefore opens on what
the graph does to the core graph: **What this graph adds** (its default rules, each with
its status, Proposed or Adopted, its legal basis and a plain explanation), then **What it
removes** and **What it replaces** when it does either, each with the legal reason, and
then its axioms, folded under a heading such as "46 axioms, the same as the core graph"
(or "44 axioms: the core graph's without the two listed above"), and the rules it keeps
from the core graph. Its Turtle download is the complete graph with a comment that names
the core version and the difference file it was built from, and the manage page says in
one line what the graph adds. Every graph page and the Viewer link to **Compare graphs**
(below). The
**Dependency Graph Editor** at `/dependency-graph/editor` is the entry page of the
writing side: it says what you can do with a graph of your own and leads to your graphs
at `/my/dependency-graphs`, or to the login if you have not signed in yet. What the
reasoning itself does with a graph is explained at `/reasoning`.

### Core graphs and your own

| | Core graph | Your graph |
|---|---|---|
| Who owns it | the project (an administrator) | you |
| Who can see it | everybody, once published | you and whoever you share it with |
| Where it is listed | `/dependency-graph`, every selector, for everybody | the same places, but only for you and the people you share it with |
| Editing and publishing | an administrator edits it in place, and publishing mints version n+1 | a draft is edited, a published one is not, and publishing moves the draft to its public address |

The editor changes a graph's statements and default rules, not what the graph says about
itself. Its title, description and date and, for a jurisdiction graph, the core graph and
version it was built from and the axioms it removes are kept from the version before when a
new version is saved or published; everything else is written as a whole, because the
graph is complete. Every default rule has an **explanation** field beside its basis: two or
three plain sentences on what the rule does to a license that is silent, why the law leads
there, and what somebody combining licenses will notice. It is shown next to the rule on
the graph pages, in the comparator and wherever the rule fires, and a rule of a core graph
cannot be saved without one. The editor of a jurisdiction graph says that the graph's source
of truth is its difference file in the DALICC repository: an administrator's edit changes
the graph on the server at once and is folded back into that file afterwards.

`dg_default` is the core graph that ships with the service, and it is what a caller who
chooses nothing reasons with. It is at version 2, which holds the review of 2026-09-23
that read every action of the vocabulary against the graph, and the endorsement rule with
its explanation, its legal basis and the name of the person who adopted it;
version 1 is the graph as it stood before the reviews of 2026. It cannot be
deprecated: withdrawing it would
silently change every answer the service gives.

### Comparing two graphs

**Compare graphs** at `/dependency-graph/compare`, in the Reasoning menu, puts two graphs
side by side the way the License Comparator puts licenses: any two you may read, the core
graph, a jurisdiction graph, or one of your own, shared with you or published. Without a
choice it compares the core graph with the European Union graph. The page opens on one line
that counts the axioms and the default rules the second graph adds, lacks and holds in a
different form, then lists them: the added statements, the ones it does not have, and the
changed ones (two relations between the same actions, or two rules for one action whose
outcome, territory, basis or explanation differ), every rule with its status, basis and
explanation. *Swap the two* turns the comparison round, every graph is linked to its page,
and the same comparison is available as JSON (`?format=json`) and through the API
(`GET /dependencygraph/compare`).

### Create, edit, share, publish

1. **Create.** `/my/dependency-graphs/new`: give it a name of at most 200 characters
   and decide what it starts from. There are three ways. Starting from a published core
   graph such as `dg_default` copies its statements (46 for `dg_default`), so
   you only have to change what you disagree with. *Upload a Turtle file* reads the
   statements out of a file on your computer (UTF-8, at most one megabyte); a file you
   downloaded from a graph here can be uploaded again exactly as it is, and you get the
   same statements back. Starting empty gives you a blank table. If you attach a file
   and also pick something under *Start from*, the file is used and the page says so.
   A file that is not Turtle, is not UTF-8, is too large or holds statements the editor
   would refuse is reported on the form and nothing is created.
2. **Edit.** `/my/dependency-graphs/{id}/edit` is a table of statements: a subject
   action, one of `odrl:includedIn`, `odrl:implies`, `owl:sameAs` and
   `dalicc:contradicts`, and an object action. Both sides are chosen from the DALICC
   vocabulary by their CURIE. Add and remove rows without JavaScript, paste Turtle into
   *Import from Turtle or a file*, attach a Turtle file there instead (the text of the
   file is put into the box so you can see what was read), or copy a core graph's
   statements in.
   Refused: an action the vocabulary does not define, a relation that is not one of the
   four, an action related to itself, and the same statement twice. Reported but
   accepted: a circle in `odrl:includedIn` or `odrl:implies`, which makes every action in
   the circle follow from every other one.
3. **Save.** Every save writes the statements into your own private graph and keeps a
   revision. Revisions are never overwritten and never deleted.
4. **Share.** The manage page shares the graph with an account as an editor (may change
   the statements) or a viewer (may read them), or invites an address that has no
   account yet. Ownership can be transferred; the previous owner stays an editor.
5. **Publish.** The statements move to `https://dalicc.net/dependencygraph/{id}`, the
   graph becomes **unlisted** (nobody else's list shows it, and the identifier is the
   only way to it) and version 1 is stored with its change log. A published graph is
   never edited: *Create new version* starts a fresh draft, and publishing that one
   deprecates its predecessor and points at the successor.

### Promotion to a core graph

An administrator can republish somebody's graph as curated data, which gives it a
permanent identifier and puts it in front of everybody. Nothing is deleted and no address
stops resolving: the statements are copied into a new core graph, and your graph is
marked deprecated with a pointer at its successor. Ask for it through a submission
(section 20).

### Choosing a graph for a task

| Where | How |
|---|---|
| License Compatibility Checker | the *Dependency graph* select; the choice rides in `?graph=` and is printed in `statements.txt` |
| License Composer | the *Dependency graph* select next to *Check consistency* |
| Dependency Graph Viewer (`/dependency-graph`) | *Graphs you can reason with*, or `?graph=<id>` |
| The API | a parameter on the compatibility check, the consistency check and the graph listing ([API.md](API.md)) |

**The seven jurisdiction graphs.** Beside the curated core graph, DALICC ships one graph
per big market: the European Union, the United States, China, the United Kingdom, Japan,
India and Brazil. Each one is complete: the core graph's axioms and its adopted rule, plus
the default rules proposed for that market, and it adopts nothing of its own. A jurisdiction
graph may also leave out an axiom of the core graph or replace one of its rules where the
law of that market does not agree with it, always with the legal reason; none of the seven
does so today. None of
them is the default for any check: choosing one in the License Compatibility Checker, the Composer or the Viewer
is a request to see what its rules would do, and the answer says on every finding which
side came from the text of a license and which from a rule. The graphs are named plainly
("European Union default rules"), because each graph is published; what is proposed is each
rule. Every rule in them is a proposal for the association's legal reviewer, the Status
column of the Viewer, the graph page and the editor says so beside every rule, and a
finding in the License Compatibility Checker or the Composer that a rule supplied reads "by default rule
(proposed)", or "(adopted)" for the core graph's rule. Nothing in them is legal advice.
[LICENSE_REVIEW.md](LICENSE_REVIEW.md#13-default-rules-and-jurisdictions) lists every rule
with the statute it rests on.

The three selects offer the same list, in the same order and in three groups: **Core
graph**, **Jurisdiction graphs (the core graph plus local default rules)**, then your graphs
and the ones somebody shared with you. An option is named
`<title> (core, default, version 2)`, `European Union default rules (version 2): the core
graph plus 9 default rules` (with "removes M axioms" and "replaces K rules" when a graph
does), `<title> (yours, version 2)`, `<title> (shared with you, version 1)` or, for a graph
that has not been published yet, `<title> (yours, draft)`. The Viewer's list and the core
list of `/my/dependency-graphs` use the same groups and lines.

**A draft can be reasoned with right away.** A draft is in every one of those selects for
you and for everybody you share it with, and for nobody else. Publishing gives the graph
a public address and a version number; it does not change what the tools can do with it.
The License Comparator has no selector, because it puts license records side by side and
does not reason.

A published core graph is accepted from anybody. A graph belonging to an account is
accepted only with that account's session or API token; anybody else gets `403`, so an
owner can tell a typo from a graph that is not theirs.

### Who may do what

The per-graph roles are the license ones, with one documented addition: a **core** graph
is curated data, so an administrator edits it in place and publishing mints the next
version instead of creating a second object. Nobody but an administrator may touch a
core graph.

| Capability | admin | owner | editor | viewer |
|---|---|---|---|---|
| See it, including a private draft | yes | yes | yes | yes |
| Change the statements of a draft | yes | yes | yes | no |
| Publish | yes | yes | no | no |
| Share it, transfer it | yes | yes | no | no |
| Deprecate a published graph | yes | yes | no | no |
| Start a new version | yes | yes | yes | no |

A published graph names its owner by display name and profile address, never by e-mail.
What is written to the record of changes is in
[ADMINISTRATION.md](ADMINISTRATION.md#10-the-audit-log).

---


## 19. Text-to-License

`/text-to-license` reads the text of a license and proposes the DALICC model for it:
the asset types, the permissions with their duties, the prohibitions and the clause
texts. What comes back is a **draft with its reasoning attached**, and it is yours to
correct before anything happens to it. Every statement carries the sentence of the
license it was read out of and a confidence, and nothing is published.

The page is available to people with an account, and an installation can open it to
everybody. It works only while an administrator has configured an access key for it;
without one the page says "The translation assistant is not configured."

The page used to be called the License Translator, and an old `/license-translator` link
or bookmark still works: it redirects here.

### Translating a text

1. Paste the license text, or upload it as a `.txt` or `.md` file. The counter under the
   box says how many characters it is and, for a long text, how many parts it will be
   read in.
2. Give it a title, or leave the box empty and take the title the assistant reads out of
   the text.
3. Tick the consent box. The text is sent to an external model provider for processing,
   so do not submit a text that is not yours to send (see *The text you submit* below).
   The line under the box names the provider your text goes to first and the ones it may
   go to instead when that one is busy; your consent covers whichever of them answers,
   and the [privacy notice](https://dalicc.net/privacy) lists them all.
4. Press **Translate**. A short license takes a few seconds; a long one is read part by
   part and takes about as many times longer.

### While it runs

A license of several parts is read in the background and a page follows it, so you can
leave it open and come back. That page tells you four things:

* **Where the run is.** One line in plain words, "Part 3 of 8 is with the provider" or
  "The parts are being put together", with a bar and a counter under it so you can see
  that the page is alive while a part is out.
* **How long is left.** An estimate from what a part of your text has taken so far. It
  appears once the first part is back and it gets better with each one.
* **What has come back.** Each part that is read adds short lines to a list:
  "Permission: Distribute" and the first words of the sentence it came from. It is a
  preview. The whole proposal, with the full quotes and the confidences, opens when the
  run is over.
* **What is missing.** A part the provider could not answer is named there and marked
  "will be offered for retry".

Without JavaScript the page still works: it offers a link to open the result, and
reloading it says whether the run is over.

### The text you submit, and what happens to it

The consent box says it plainly: "The text you submit is sent to an external model
provider for processing. Do not submit confidential texts." Both the page and the API
refuse to run without that consent.

DALICC does not keep the text you submit. It records one row per run with your account,
how long the text was, how many parts it was read in, what the run cost and what came of
it. The proposal quotes the text it was read from, so it is held for a couple of hours,
long enough for the page to collect it, and then removed. After that the only place the
content survives is the draft you chose to save, which is private to you like any other
draft. What the provider keeps is the provider's business and outside DALICC's control.
Do not submit anything that is not already public; a license text usually is.

A long license can change provider in the middle of a run, when the first one is out of
its allowance. The result page says which provider answered.

### Reading the result

| Panel | What to do with it |
|---|---|
| Check these first | contradictions and anything the assistant was unsure about |
| Proposed statements | one row per statement, with the **quote** it came from and a confidence bar. Read the quote, not the label |
| What the library adds by convention | the statements no sentence of your text states, grouped by the rule that added them |
| The library already has ... | the curated record for this license, next to your reading, with the differences in three columns |
| Clauses the vocabulary cannot express | not part of the model. Worth reading: a recurring one is a candidate for a new vocabulary term |
| Did you mean one of these? | clauses that read like a term DALICC has, but not clearly enough to record without asking. Read the quote, then press the button to add the term or leave the clause alone |
| Consistency check | the same check the License Composer runs before publishing |
| Metadata | the title, the asset types, the validity and the clause texts, quoted verbatim |

A row with a peach background names a term that is not in the DALICC vocabulary. It was
left out of the model on purpose, and it usually means the assistant reached for
something that does not exist.

The column **Where it comes from** says of every statement whether the assistant quoted
it or the library added it. The assistant records only what it can quote, and the curated
records carry a little more, so that two licenses of one family are modelled the same
way. Those statements are marked **library convention**, the block under the table says
which rule added each one and why, and each has a **Keep this statement** box. Clear the
box and the statement is left out of the composer, the draft and the download, so nothing
you disagree with travels any further.

If the strip above the table says that some parts could not be read, **Try the parts
that failed again** reads only those and merges what comes back into what you are already
looking at. Nothing that worked is translated twice.

**What the library already says.** Most texts people read here are texts the library
already models, so the page looks the curated record up and shows it next to your
reading. Where nothing matches, the block says *Closest record in the library* and how
close it is, which is a hint rather than an answer.

The table has three columns: what only your reading says, what both say, and what only
the record says. A duty they both state but hang in different places gets a row of its
own,
because that is the difference a reading gets wrong most often: a text states a duty
once, under distribution, and the curated record repeats it on every permission it
applies to. *Adopt the library model* takes the record's set over whole, keeping the
quotes your reading found for the statements the two agree on; the box next to a row
takes over that one row. Adopting changes only what is on the page, and whatever you
adopt is what the three buttons below carry.

Then one of three things:

* **Open in composer** fills the License Composer in with the proposal, where you can
  correct it, check it again and publish it as your own license. The whole proposal
  travels, including the statements the questions cannot express, which the composer
  lists under *Further statements from the reading* (section 7);
* **Save as draft** writes it straight into your private drafts and opens it under
  *My licenses*. Nothing is public until you publish it;
* **Download JSON** gives you the whole proposal, evidence included, to keep or to send
  through the API.

### What it can and cannot do

* **The output is a draft.** A machine's reading of the text, wrong often enough that
  publishing one unreviewed would put a wrong model on a permanent address. Check every
  statement against the quote next to it.
* **A quote is evidence, not proof.** It is copied from the text, but whether it supports
  the statement is a judgement, and that judgement is yours.
* **Confidence is self-reported.** It ranks statements within one run; it is not a
  probability.
* **Silence is not a prohibition.** The assistant still sometimes proposes a prohibition
  where the text simply grants nothing, and the consistency check does not catch that:
  only reading does.
* **An invented term is dropped, not accepted.** A term the vocabulary does not have is
  kept in the result, left out of the model and reported as a warning. One the assistant
  keeps reaching for may be a real gap in the vocabulary.
* **A long license is read in parts**, and a statement that depends on two distant
  sections may be missed by both. The overlap between parts reduces that, it does not
  remove it.
* **Nothing here is legal advice.** The model is a machine-readable summary; the license
  text is the license.

### What it costs you

The strip above the form says three numbers: how many requests the assistant has left at
the provider and when they come back, how many translations you have run today out of
your daily allowance, and how many the whole deployment has run. When the provider is out
of requests the page says so with a countdown and the button is switched off; nothing is
spent finding out.

Your daily allowance is ten translations by default. An administrator can raise or lower
it for your account, and the installation as a whole has a daily allowance of its own.

The settings an administrator controls, and what the last runs cost, are in
[ADMINISTRATION.md](ADMINISTRATION.md#8-the-assistant-settings). The API is in
[API.md](API.md); how the assistant reads a text is in
[TRANSLATION.md](TRANSLATION.md).

---


## 19a. License-to-Text

*License-to-Text* is the other direction of section 19. It takes a DALICC license model
and writes the license text for it in plain English: what you may do, what you must do,
what you may not do, and the further terms. It is at
[/license-to-text](https://dalicc.net/license-to-text), in the Tools menu under
Text-to-License, and there is a *Write this as a license text* link on every license
page.

The page is available to people with an account, and an installation can open it to
everybody. The composer has its own button of the same name and does not come here: it
writes the text into the *License text* section of the form, where you can correct it
and keep it with the license (section 7). This page is for a license of the library and
for a model you have on disk.

It changes nothing. Nothing is published, nothing is saved, and the license itself is
untouched. What you get is prose to read, to check and to keep.

### What you give it

One of three things:

* the **identifier or address** of a license, curated (`Apache-2.0`) or unlisted (the
  32-character identifier of a license you composed);
* a **pasted model**, as Turtle or JSON-LD, exactly as the *Download* buttons on a
  license page give it to you. This is how a license that never left your machine is
  read;
* the **license you have just composed**, by its 32-character identifier once you have
  published it. While you are still composing, the button in the *License text* section
  of the composer writes the text into that page instead.

### What you get

A title, a short preamble, numbered sections in the order permissions, conditions,
prohibitions and further terms, and a closing sentence. Every section lists the terms of
the model it covers, under the section itself, so you can see what a sentence was
written from.

Under the text there is either a line saying that every term of the model is covered, or
a **Not covered** note naming the terms the text missed. The note matters: a license text
that reads smoothly and leaves out a duty is worse than one that says it awkwardly, and
the note is the only way to tell the two apart at a glance.

The text can be saved as a `.txt` or a `.md` file. The page shows it once and keeps
nothing.

### Who wrote the text

Two writers produce the same structure, and the page says which one answered.

* **The assistant.** The model is sent to an external provider, which writes the prose.
  This is the readable one. The result page names the provider that answered.
* **DALICC itself.** A deterministic writer builds the text from the definitions in the
  [DALICC vocabulary](https://dalicc.net/ns). It is plainer, and it always covers the
  model in full. It answers whenever the assistant is not configured on the deployment,
  your allowance for the day is used up, or the provider does not answer, so the feature
  always gives you a text.

The deterministic text alone is also a plain link, with no account and no allowance:
`https://dalicc.net/licenselibrary/license/Apache-2.0?format=text`, which is what
*Download* > *Text* on a license page gives you. Where the license carries a license
text of its own, that link gives you that text instead, because it is the license rather
than a reading of it.

### Names, and what is sent

The model goes to the same providers as Text-to-License, in the same order, and the line
under the form names them. A curated record carries no personal data; a license you
composed carries the name you entered, so the form offers *Send the model without names*,
which turns the creator, the licensor and the publisher into "the licensor" before
anything leaves DALICC. It is ticked by default for a composed license and unticked for a
library record, where the publisher is a fact about the license. The composer's own button
always leaves the names out. See the [privacy notice](https://dalicc.net/privacy).

### The allowance

License-to-Text has a daily allowance of its own: writing a license text never takes a
translation away, and running a translation never takes a license text away. Unless an
administrator sets a figure for it, you may write as many license texts a day as you may
run translations, and the strip above the form says what is left before you press the
button (section 19). The deterministic writer costs nothing and is never counted.

An administrator may switch License-to-Text off for the whole installation, or limit how
many license texts an account may write in a day. Switched off, the page, the composer's
button and the API say so; the plain text link above keeps working, because it asks no
provider.

The text is generated from the machine-readable model and is not legal advice. Only the
license itself is binding.

---


## 20. Submissions, correction requests and the inbox

The DALICC library is two different things. One half is **yours**: the licenses you
compose and the dependency graphs you write, private until you publish them, unlisted
afterwards. The other half is **curated**: the records everybody searches and the graph
the compatibility checker reasons with. Nobody owns the curated half, which is why
changing it is a request rather than an edit.

### Offer something of yours for the curated library

1. Publish it first. A draft is private, so a curator could not read it.
2. Open its manage page (`/my/licenses/{id}` or `/my/dependency-graphs/{id}`) and choose
   **Submit for review as a core license** (or **Submit for review as a core graph**).
3. Say in a few sentences why it belongs there: who uses it, where the legal text is,
   what makes it worth curating. You may propose the identifier it should get; the
   curators assign the final one.

What happens next is on `/my/submissions`: the status, the conversation, and a
**Withdraw the submission** button while nobody has decided. When a curator asks for changes, change
your own copy (publishing a new version of it is the normal way) and press **Submit it
again**.

| Status | What it means |
|---|---|
| Submitted | It is in the queue. |
| In review | A curator is reading it. |
| Changes requested | Something has to change before it can be accepted; the note says what. |
| Approved | Accepted, waiting to be published as a curated record. |
| Published | A curated record was created; the page links it. |
| Rejected | It will not be curated; the note says why. |
| Withdrawn | You took it back. You can submit it again. |

Nothing is moved, renamed or deleted when a submission is published. A **new** curated
record is created that says the same thing, names your license as its source and you as
its creator, and starts at version 1. Your own license keeps its address, its owner and
its history.

### Report that a curated record is wrong

Anybody with an account can. On a curated license page, or on `/dependency-graph`,
choose **Request a correction**. A visitor without an account gets *Report an issue* in
the same place, an e-mail link.

The form is structured on purpose. Each row names

* **which field** is wrong (the list under the form shows what the record says today,
  and picking a field fills the next box in for you),
* **what it says now**,
* **what it should say**,
* **why**: the clause or the section of the license text that says so.

At least one row is needed; the free-text box is for everything a row cannot hold. Your
requests are on `/my/requests`, with the conversation and a **Withdraw the request**
button while nobody has decided.

A request is **resolved automatically**: when a curator publishes the corrected version
naming your request, the status changes and the new version is linked in the
conversation. Nothing has to be closed by hand.

| Status | What it means |
|---|---|
| Open | It is in the queue. |
| In review | A curator is reading it. |
| Accepted | The curators agree; the correction is being made. |
| Resolved | A published version answers it. |
| Rejected | The record is right as it stands; the note says why. |
| Closed | Withdrawn, or set aside with a reason. |

### The inbox

`/inbox` is one page for everything DALICC has to tell you and everything you want to
say back:

* a **notification strip** at the top, newest first, with a link to what it is about;
* the **conversations** you take part in, with the number of messages you have not read;
* a switch for the notification e-mails (see below).

Opening a conversation marks it read, and the badge in the account menu ("Inbox (3)")
goes down. Messages are written in markdown: a list, a link, a code block. HTML is
removed rather than shown. Messages DALICC writes itself, such as "Ada Admin approved
this submission", are marked as system messages and cannot be written by anybody.

You are in a conversation when it is about something of yours (a submission, a request,
a license or a graph you own or were given access to), or when somebody started one with
you. Nobody else can open it, administrator or not, except for the two queue kinds
(submissions and correction requests), which every administrator reads because that is
what the queue is.

**No e-mail addresses are shown.** Everybody is named by their display name, whoever is
reading. Addresses stay in the administration pages.

To write to the DALICC team about something that is not a submission or a correction,
use **Contact the administrators** on `/inbox`. An administrator writing to one account
uses **Message** on `/admin/users/{id}`.

### Notification e-mails

Every notification always appears in your inbox. When the installation has a mail server,
which an operator sets up
([OPERATIONS.md](OPERATIONS.md#43-outgoing-mail-and-what-happens-without-it)), the
notification is mailed to you as well. The subject is `[DALICC] <kind>: <subject>`, and
the mail carries a one-line summary, the message it is about and a link back. You can
switch those mails off on `/inbox` or `/account/notifications`; the default is on. When
there is no mail server the page says so and nothing is sent.

A mail server that is down never fails what you were doing: the notification is in your
inbox either way, and the inbox shows which ones went out by e-mail.

### What the curators do with it

You see every step in your own conversation, so there is no queue to watch and nothing
to chase. The pages the curators work in are in
[ADMINISTRATION.md](ADMINISTRATION.md#3-the-review-queue-and-correction-requests).

### Who may do what

| Capability | anonymous | member | admin |
|---|---|---|---|
| Report a problem by e-mail | yes | yes | yes |
| Raise a correction request | no | yes | yes |
| Submit something of your own | no | yes (owner) | yes |
| Withdraw or resubmit your own | no | yes | yes |
| Read the review and correction queues | no | no | yes |
| Decide, publish, resolve | no | no | yes |
| Read a conversation | no | only as a participant | queue threads always |
| Start a conversation with one account | no | with the administrators | with anybody |

Every status change is recorded four times over: on the submission or the request itself
(who decided, when and with which note), as a message in the conversation, as a
notification for the people it concerns, and in the record of changes an administrator
can read. Nothing is deleted; a withdrawal is a status, not an erasure.

---


## 21. API limits and usage

Everything below is about requests made with a **personal API token**. Pages you open in
a browser are not affected: they are protected by the per-IP limits described in
[API.md](API.md#rate-limits).

### How much one account may ask for

Four windows apply at the same time, and a request has to fit in all of them:

| Window | Requests by default |
|---|---|
| per second | 5 |
| per minute | 60 |
| per hour | 1000 |
| per day | 10000 |

An administrator can raise or lower all four for one account, and the installation has
defaults of its own.

They are counted **per account, not per token**. A second token does not give you a
second allowance, and revoking one token does not free anything for the others. That is
deliberate: a token is a credential, not a quota.

An expensive call counts as more than one request, because that is what it costs DALICC:
a compatibility check as five, a consistency check as three, a translation as ten, and
everything else as one ([API.md](API.md#weights)).

On top of the per-account windows there is a ceiling across all token traffic together,
600 requests a minute by default. Reaching it answers `429` with a message that says the
service is busy rather than that you are over your own limit.

### What you see

`/account/tokens` shows "Your API limits" with a row per window: how much you have used,
what the limit is, what is left, and how many seconds until the window restarts. The
token table on the same page shows when each token was last used, which is how you find
the one a forgotten script is still running.

Every answer to a token request carries `X-RateLimit-Limit`, `X-RateLimit-Remaining` and
`X-RateLimit-Reset` for the window closest to refusing your next call. Going over a limit
is `429` with `Retry-After` and a body naming the window. The exact shapes are in
[API.md](API.md#429).

### If your allowance is too small

Ask an administrator. They can see what your account has been calling, and they can raise
the four numbers for your account alone, without a restart and without changing anybody
else's allowance. How they do it is in
[ADMINISTRATION.md](ADMINISTRATION.md#7-api-usage-and-per-account-limits). Lowering what
everybody may ask for is a change to the installation itself and belongs to an operator
([DEPLOYMENT.md](DEPLOYMENT.md#47-per-account-api-limits)).

---


## 22. Your data

What DALICC processes about you, why, how long it keeps it and who else sees it is on
one page: [dalicc.net/privacy](https://dalicc.net/privacy), linked from the footer of
every page and from every form that collects something. It is written per workflow, with
the retention periods the service really uses, so you can look up one thing without
reading the rest.

**When the notice changes.** The end of the page prints its version and the date it was
last changed, and the version that was on screen when you accepted your invitation is
recorded with your account, so you can find out what you agreed to. When something
changes that you would want to know about, the next page you open while signed in
carries a banner that says so, with the list of changes folded under **What changed**
(open it to read them), a link to the page and an **I have read it**
button that records that you saw it. The banner blocks nothing and asks for no consent:
where consent is needed it is asked for on the form that collects the data.

Two of your rights need no message to anybody.

**A copy of what your account holds.** `/account/export` downloads one JSON file with
your profile, your licenses and dependency graphs with the RDF of each and every saved
version of them, your submissions and correction requests, the conversations you take
part in with the messages everybody wrote in them, the notes written for you, the
invitations you received and sent, your runs of the two assistants, your recent API
requests and the limits set on your account, the publisher name reserved for you, and
the audit entries about your account and the things it owns. No password hash, no token
value and no one-time link is in it: those are keys, not information about you.

**Deleting your account.** `/account/delete` lists what is deleted and what stays, then
asks for your password and a tick. An account that signs in through your organisation
has no password, so the page says "Your account signs in through your organisation, so
no password is asked for." and asks for the tick and a recent sign-in instead: if you
signed in more than 15 minutes ago, sign in again through your organisation first. It
replaces your name and your e-mail address with
placeholders, clears your password, revokes your tokens, ends every session, removes
your notification settings and every note written for you, deletes your unpublished
licenses and dependency graphs with all their saved versions, deletes the invitations
that brought you here and the ones you sent, and takes your account id off the runs of
the two assistants. It cannot be undone, and the placeholder address can neither sign in
nor be invited back.

What deletion does **not** change is what other people rely on. A published license
stays public, keeps its address and keeps the creator name on it: a license has to say
who granted it, and a grant by nobody is not a grant. Your submissions, correction
requests and messages stay as the record of the review, because other people took part
in it. Every page that shows your name reads it from your account, so it becomes the
placeholder there; a system line written before September 2026 may still spell your name
out, because those lines were stored with the name in them, and the association will
redact one on request.

**Withdrawing a license first.** Deleting the account does not withdraw anything. If you
no longer stand behind the terms of a license you published, mark it withdrawn: its
address keeps working, its terms stay readable for the people who already rely on them,
and its page says from which date it is withdrawn. Each license has the action on its own
page, and the delete page offers it for all of them before you confirm. If you want the
name taken off a withdrawn license as well, write to the addresses on the
[privacy notice](https://dalicc.net/privacy) and say which one; the association decides
such a request.

**Changing your name.** A new name appears everywhere the site draws it, from then on,
but a license you have already published keeps the name it was published with, the way a
signature does. If one is wrong, write to us and it is corrected as a new version.

If you cannot sign in any more, write to the addresses on the
[contact page](https://dalicc.net/contact) and an administrator does the same thing from
your account page. Anything else, a correction or an objection, is a message to the same
addresses: it needs a person to read it.

---

**Reference.** The addresses of the pages this manual talks about.

## 23. Where to find things

**Pages anybody may open**

| Page | What it is |
|---|---|
| `/` | the home page |
| `/licenses` | the Licenses menu group: what the library, the search, the comparator and your shortlist each do |
| `/tools` | the Tools menu group: what the Composer, Text-to-License, License-to-Text, the License Compatibility Checker and the GitHub License Compatibility Checker each do |
| `/api` | the API: the interactive documentation, the reference, the Python client, and tokens and limits |
| `/license-library` | the list, with the keyword box and the port groups |
| `/license-library/{id}` | one license |
| `/license-library/{id}/versions/{n}` | an archived version of a curated record |
| `/license-library/changes` | recent changes across the library |
| `/license-search` | the faceted questionnaire |
| `/license-composer` | the composer |
| `/license-comparator` | the side by side matrix |
| `/license-compatibility-checker` | the bundle, the compatibility check and the statement |
| `/reasoning` | how the reasoning works, step by step |
| `/dependency-graph` | the Dependency Graph Viewer: the core dependency graphs and their axioms |
| `/dependency-graph/editor` | the Dependency Graph Editor: what the editor does, and the way in |
| `/github-license-compatibility-checker` | the repository dependency check |
| `/bookmarks` | My Bookmarks: your shortlist, kept in your browser |
| `/ns` | the vocabulary |
| `/documentation` | where the documentation is: the user guide, the vocabulary, and the public repositories of the data and the Python client |
| `/documentation/guide` | the user guide itself: the introduction, this manual, administration, the API, the Python client and the licensing documents |
| `/documentation/glossary` | the glossary of section 24, one entry per term, each with its own address |
| `/docs` | the interactive API reference of version 1.1 |
| `/v2`, `/v2/docs` | version 2 of the API: what it offers, and its interactive reference |
| `/blog`, `/blog/{slug}`, `/blog/feed.xml` | the blog and its feed |
| `/about`, `/dalicc-nutshell`, `/publications-presentations`, `/changelog`, `/contact`, `/imprint` | the content pages |
| `/privacy` | the privacy notice: what is processed, per workflow, and your rights |
| `/users/{id}` | somebody's public profile: their name and what they have published |

**Pages that need an account**

| Page | What it is |
|---|---|
| `/account` | your profile, and the way to the rest |
| `/change-password` | your password (`/account/password` leads there; the button that ends every other session is on `/account`) |
| `/account/tokens` | your API tokens, your limits and your usage |
| `/account/notifications` | the notification e-mail switch |
| `/account/export`, `/account/delete` | a copy of your data, and deleting your account |
| `/my/licenses`, `/my/licenses/{id}` | your licenses and one manage page |
| `/my/dependency-graphs`, `/my/dependency-graphs/{id}` | your dependency graphs |
| `/my/submissions`, `/my/requests` | what you offered and what you reported |
| `/inbox` | notifications and conversations |
| `/text-to-license` | Text-to-License |
| `/license-to-text` | License-to-Text: a license model written out as a license text |

The pages under `/admin` are listed in
[ADMINISTRATION.md](ADMINISTRATION.md#11-where-the-administration-pages-are). The same
objects over the API are in [API.md](API.md), and the Python client that wraps them is in
[SDK.md](SDK.md).

---

## 24. Glossary

The words the site uses in a sense of its own, in alphabetical order. The same entries
are on one page of their own at `/documentation/glossary`, and the explanations on the
record pages and the graph pages link to them.

### Adopted

The status of a default rule the library applies as its own convention. One rule is
adopted: in the core graph, a license that says nothing about endorsement grants no right
to use the licensor's name or marks to endorse a product. A finding that rests on it reads
*by default rule (adopted)*. See [proposed](#proposed).

### Conflict

In a compatibility check, two statements that no combined work can meet together: one
license requires what another prohibits, two duties cannot both be met, or two licenses
each require the whole work to stay under themselves and no "or later" option or
compatibility clause leads from one to the other (GPL-2.0-only and GPL-3.0-only). One
conflict makes the verdict *Cannot be combined*. Compare [restriction](#restriction).

### Default rule

A statement of a [dependency graph](#dependency-graph) about an act a license says nothing
about: which act, what applies to it (not granted, granted, required, or a term the law
does not let a license set aside), in which territory, and the statute or principle it
rests on. A default rule is not part of any [record](#record). A check supplies it only
for a license that is silent, and every finding says which side came from the text and
which from a rule. Each rule is either [adopted](#adopted) or [proposed](#proposed). None
of it is legal advice.

### Dependency graph

What the checks reason with: the statements about how the actions relate to each other
(Grant use is the same act as Sublicense, Distribute is included in Use) and the
[default rules](#default-rule). The core graph is the one a check uses when you choose
nothing; seven jurisdiction graphs add the rules proposed for one market each. Section 18
has the details.

### Edition

The same license text reissued by another body in the same legal system, for example
the Open Supreme Court Licence as an edition of the UK Open Government Licence. The
record page says *Edition of* and names the license it reissues, which lists the edition
under *Jurisdiction ports and editions*.

### Exception

A [variant](#variant) that reads a license together with an SPDX exception, which lifts
one of its conditions. `GPL-2.0-only-with-Classpath-exception-2.0` is GPL-2.0-only with
the Classpath exception, which lets independent modules linked with the covered code be
distributed under terms of their own.

### License

The legal text a licensor publishes: the words that grant the rights and set the
conditions. DALICC does not hold licenses as texts; it holds [records](#record) of them,
and links each record to its text. When the home page counts licenses, it counts the
distinct legal texts the library models.

### License owner

The account that holds a license composed on DALICC. It publishes the license, shares it,
starts new versions and can [withdraw](#withdrawn) it. DALICC does not check that this
account holds the rights it licenses, and it does not review the terms. A curated record
has no License owner; the association maintains it.

### Port

Short for jurisdiction port: a license adapted to the law of one country, such as
Creative Commons Attribution 3.0 Austria. A port has a [record](#record) of its own, and
the library lists it folded under the license it comes from. DALICC groups the Creative
Commons ports of versions 2.0 to 3.0 under the 4.0 International license of the same
elements, although their texts differ from it.

### Proposed

The status of every [default rule](#default-rule) but one: a reading of the law put
forward for the association's legal reviewer, a role that is not yet filled. The 27 rules
of the seven jurisdiction graphs are proposed. A proposed rule applies only when you choose
its graph, and a finding that rests on one reads *by default rule (proposed)*. In a
review record, a finding marked proposed suggests a change to the record that nobody has
decided yet.

### Record

DALICC's machine-readable model of one [license](#license): what it permits, prohibits and
requires, the clauses it quotes, and where the legal text is. Every record has its own
identifier and permanent address, `https://dalicc.net/licenselibrary/<id>`. One license
can have several records, one for itself and one for each [port](#port), [edition](#edition)
or [variant](#variant). The record is published under CC BY 4.0; the license it describes
belongs to its publisher.

### Restriction

In a compatibility check, one license permits an act that another prohibits. The works
can still be combined, but the combined work may not do that act. The MIT License permits
changing the license and GPL-3.0 prohibits it, so MIT code can go into a GPL-3.0 work and
the result stays under GPL-3.0. A license that names another as compatible gives the
restriction "The combined work has to be released under" that license. Restrictions alone
make the verdict *Can be combined with restrictions*. Compare [conflict](#conflict).

### Rider

A [variant](#variant) that adds a condition to a license.
`Apache-2.0-with-Commons-Clause` is the Apache License 2.0 with the Commons Clause, which
withholds the right to sell the software.

### Statement origin

Where a permission, a prohibition or a duty comes from. The record page marks each one:

* *from the text*: the library's reading of a sentence of the license. Where the record
  keeps that sentence, the "?" beside the statement quotes it.
* *by library convention*: the text is not explicit, and the library states it for every
  license of the kind. The "?" names the convention, for example a family rule.
* *by default rule*: not a statement of the license at all, but one a
  [default rule](#default-rule) of the dependency graph supplies because the license is
  silent, marked *(proposed)* or *(adopted)*.

### Superseded

A version that a newer version replaces. The page of the old version says *A newer
version exists* and links the new one. Its address keeps working, and rights already
granted under it are not affected by the new version. Compare [withdrawn](#withdrawn).

### Variant

A record that models the legal text of another record with one thing changed. There are
three kinds: the or-later form of a license (`GPL-2.0-or-later` beside `GPL-2.0-only`), an
[exception](#exception) and a [rider](#rider). Unlike a [port](#port), a variant is a
license of its own: listed, searched and counted like any other, and its page names the
record it varies.

### Withdrawn

A license its publisher no longer offers for new uses. The [License owner](#license-owner)
or an administrator sets it with *Withdraw this license* on the manage page. The page says
*Withdrawn by its publisher* and gives the date. Nothing is deleted: the terms stay
readable, and whether rights already granted continue is decided by the license's own
terms. Compare [superseded](#superseded).
