docs← Back to article

Markdown for LLMs

Audit surface: relations, functions, questions, lints

The source Markdown for this article. Copy it into your assistant or download it as a text file.

Download this articlePlain text ↗
# Audit surface: relations, functions, questions, lints

Vocabulary can be inspected structurally without running a single rule.
This page documents the read-only audit surface: fourteen relations and
nine functions over compiled packages, six catalogued questions, sixteen
structural lints, and the command that runs them.

Two statuses apply here, and they answer different questions:

- What you can write: the relations, functions, questions, and lints
  are the supported LawQL language — **available in the public
  release** (S).
- What you can run: the `./law query` command that executes them
  **requires a source checkout** (I). It is absent from the public
  release, so the commands below use the checkout launcher `./law` from
  the repository root; see [Before you
  start](/corpus/lab/#before-you-start).

The full status legend is on the
[topic index](/corpus/#how-this-topic-marks-confidence).

## Relations and functions

Fourteen relations expose the structure of compiled packages: nodes,
edges, anchors, labels, positions, windows, imports, links, fields,
literals, variables, rules, norms, and interpretations (**S**). Every row
carries provenance back to the compiled nodes it came from. Nine
functions complement the relations: seven structural string and label
helpers plus two materialized readers over evaluation documents (**S**).

The structural layer answers equality and membership only — no
arithmetic, no ordering, no recursion, no free negation. Scoping
restricts a relation to one package or to a glob over the corpus.

## Named questions

Six catalogued questions answer the everyday "who produces / who reads"
queries (**S**). In English, with their parameters:

| Question | Parameters | What it answers |
|---|---|---|
| `anchors-of` | node, pkg | Which pinned source fragments the node relies on: act, locator, and fragment of each anchor |
| `imports-of` | pkg | Which packages the package imports, with their pinned `semanticHash` |
| `links-of` | node, pkg | All typed links of the node: produces, reads, anchored, alias, subtype |
| `producers` | predicate, pkg | Which rules have the predicate as their head, with strength, polarity, and anchors |
| `readers` | predicate, pkg | Which rule, norm, and constraint bodies read the predicate (heads are listed by `producers`); a glob in `pkg` shows reads from other packages |
| `type-step` | type, pkg | One step of a subject's type chain — an alias or subtype from the named type to its target; ask again with the result to take the next step |

The catalogue itself prints its descriptions in Russian, the language of
the project's internal tooling. The listing below is verbatim, observed
live 2026-10-03 (`./law query --list`, **requires a source checkout**):

```
$ ./law query --list
anchors-of (node, pkg) — На какие закреплённые фрагменты опирается узел — акт, локатор и фрагмент каждого якоря.
imports-of (pkg) — Что импортирует пакет — имена импортированных пакетов и их закреплённые semanticHash.
links-of (node, pkg) — Все типизированные связи узла по отношению links — produces, reads, anchored, alias, subtype.
producers (predicate, pkg) — Кто производит предикат в пакете — правила с этой головой, их сила, полярность и якоря.
readers (predicate, pkg) — Кто читает предикат — литералы тел правил, норм и ограничений (головы исключены: их перечисляет producers); pkg может быть глобом, тогда видно чтение из других пакетов.
type-step (type, pkg) — Один шаг цепочки типов субъекта — alias или subtype от названного типа к цели; следующий шаг — тот же вопрос с полученным to и пакетом цели.
```

The same listing carries the sixteen lints below, for twenty-two
catalogue entries in total. (`./law query --list` exits 0.)

## Structural lints

Sixteen lints flag suspicious vocabulary and rule shapes without
executing anything (**S**):

- `strict-negative-head`, `duplicate-declaration-label`,
  `dangling-const-ref`
- `anchored-relation-without-executable`,
  `aggregate-head-without-key`, `achievement-open-window`
- `defeater-collision-without-direct-priority`,
  `defeater-head-variable-unless`, `same-side-priority-review`
- `deontic-action-in-premise`, `derived-maintenance-condition`
- `evaluative-fact-without-producer`,
  `evaluative-head-from-nonevaluative-body`
- `interpretation-without-group`, `strict-interpretation-consumer`,
  `strict-reader-of-foreign-defeasible-head`

Running the lints **requires a source checkout** (I). The checkout
build's `law audit` command, run from the repository root against a
project directory, runs the lint catalogue over a fresh snapshot as its
form section. The public release also has `law audit`, but it ships no
lint catalog, so its audit reports that section as `not_run`. Observed
on the parcels interface fixture:

```
$ ./law audit docs/corpus/lab/fixtures/parcels-iface
law audit labparcels.iface — formalization measure §33.1 (E-0249), profile static
CLIR lowered from sources (imports: deps); freshness: verified
levels not computed by this implementation: STRUCTURED, SEMANTIC

form (LawQL catalog lints on fresh snapshot, DECISION-0394): detectors 16, findings 0
dangling premises: 0 (unsupplied by package 0, enum variants in body 0)
one-way premises: 0 of 0 rules
```

Line by line: the header names the package and the measure profile;
the second line says the compiled form was rebuilt from sources and is
fresh; the third says two higher levels are not computed here. The
`form` line is the lint section: sixteen detectors ran and found
nothing. `dangling premises` counts rule premises that nothing in the
package supplies. `one-way premises` counts strict rules whose single
premise is derived and read by nothing else and whose conclusion nobody
reads. Both are zero here.

Sixteen detectors, zero findings: the vocabulary has none of the
suspicious shapes above. Use it after every vocabulary migration and
before every review.

## Inference queries

Beyond the structural layer, a query-over form compiles an ephemeral
package and runs the evaluator over it, so authors can ask "what would
follow if" questions without writing a throwaway package (**S**). The
negative boundary — what the query surface refuses and why — is
documented alongside the reference.

## Where to go next

- The companion page on [contracts](/corpus/vocabulary/contracts/) explains the rules these lints enforce.
- The companion page on [migrations](/corpus/vocabulary/migrations/) uses this surface to confirm a move.
- For the full reference, see [LawQL](/lawql/).
- For construct-level detail, see [the Vocabulary construct reference](/constructs/vocabulary/).