Skip to content

Authoring checks (rules)

A rule is one checkable requirement — a code clause, a design standard, a firm convention. This page explains how rules are written, compiled, validated, and promoted so they become part of your workspace's canonical ruleset.

You usually don't write rules by hand

The fastest path is to ask the Setup agent ("Author a rule that checks…"). It drafts the rule, compiles it, runs it against your open model, and — once it looks right — promotes it. The mechanics below are what happens under the hood, and what to look at when you want to review or refine a rule yourself.

Two kinds of rule

Kind How it checks Lives as
Deterministic C# code that reads the model and decides pass/fail precisely Test.cs
AI check A prompt that reasons over model data / sheet evidence prompt.md
Hybrid Both — deterministic gate plus AI judgment Test.cs + prompt.md

Every rule also has a spec.yaml — its metadata: id, title, discipline, severity, category, and the kind of test. A README.md captures the rationale.

How a deterministic rule works

A deterministic rule is a small C# class that implements VitruAI's rule contract: it exposes its spec and an Evaluate(...) method that sweeps the model (rooms, elements, parameters, geometry) and returns findings with a status and evidence.

Rules are read-only against your model by design. Before any rule compiles, it passes a safety check that rejects anything that could change your model or reach outside it — file system access, network calls, launching processes, or Revit document mutations (creating, deleting, or editing elements). A rule can read and report; it can't modify.

Author → compile → validate → promote

DRAFT          Setup agent (or you) writes spec.yaml + Test.cs into  rules-proposals/<id>/
   │
COMPILE        compile_csharp:  safety pre-pass  →  compile  →  cached, ready to run
   │           (rejections or compile errors come back so the draft can be fixed)
   │
VALIDATE       run it against the open model and inspect findings against the matrix:
   │             • true positive  — a real problem IS flagged, with actionable evidence
   │             • true negative  — a compliant element is NOT flagged
   │             • false positive — a compliant element wrongly flagged  (the trust-killer)
   │             • false negative — a real problem silently passed
   │
PROMOTE        once it behaves, the Setup agent moves it  rules-proposals/ → rules/  (canonical)
               and updates the discipline index so the Coordinator routes to it

Running a rule while authoring vs. a stored rule

  • A freshly compiled draft is run by its compiled handle — used during authoring to iterate quickly in the current session.
  • A stored (promoted) rule is run by its rule id from the workspace. This is what the Coordinator and specialists use during a normal check; it reads the rule's definition from rules/ and runs it.

Either way, findings are captured and written to the run's report (see Concepts → Reports).

Validating a rule ("tests")

There is no separate unit-test framework — validation is empirical. You run the rule against a real model (ideally one with known good and known bad cases) and confirm it lands the true/false-positive/negative matrix above. A rule that produces false positives is the most damaging, because it erodes trust in every other result — so the bar for promotion is "no false positives on the validation model, real problems caught with actionable evidence."

The rule's README.md is where that reasoning is recorded, so a reviewer can see why the rule is trusted, not just that it passed.

Where rules live

  • Drafts: projects/<project>/qaqc/rules-proposals/<id>/ — anyone with access can author here.
  • Canonical: projects/<project>/qaqc/rules/<id>/ — promoted, active rules. The Setup agent owns promotion so the discipline index stays consistent (see Working with workspaces).

See also