Everything here is a declaration.
The policy is the part everyone expects to declare. So are the screens a reviewer works in, the entities the engine reasons about, the roles, the queues, the actions, and the fields that count as sensitive.
Declared, so changing any of it needs no release.
What you declare
| Declared | What it covers |
|---|---|
| Rules and signals | conditions, effects, constants, the state a rule keeps, the functions it calls and the profiles it calls them through |
| Entities | what the engine reasons about, their fields and their statuses |
| Appearance | colors, fonts, heading sizes, density, what is on screen at all — per tenant and per user |
| Screens | what an operator or a reviewer works in, their columns, filters and routes |
| Actions | what a rule may do, and who is allowed to invoke each one |
| Parameters | the settings an operator changes without a release, per tenant |
| Tamper-evidence | which tables get a hash chain, and the condition that says from which moment a row is covered |
| Audit behavior | what is recorded, at what depth, and what a message says when something is refused |
hitl_cases_list:
entity: hitl_case
route: /hitl/cases
columns: [created_at, queue, entity_id, event_type, status, priority, case_type,
assigned_to, decision, case_id] That is the review queue an operator opens, written like a rule. Add a column, change the route, split one queue into two — each is a declaration.
The claims this makes true
| The claim | Why it holds |
|---|---|
| A review queue shaped to your team | the queue and its screens are declared |
| Running in weeks | nothing was built for it; it was declared |
| A control your auditor asks for is usually configuration | the control and its evidence are both declarations |
| Adapting it to your integration is configuration | you are changing a declaration, and the product stays the product |
It is also why so little here is fixed behavior. What a queue does when nobody works it, what a gateway does when the engine is unreachable, what happens to an event no rule matched: each is yours to declare. A vendor who hard-wires them has decided something about your operation without asking.
The look is declared too
| Declared | What it covers |
|---|---|
| Colors and fonts | light and dark are declared separately, so you set each one |
| Typography and density | heading sizes and line heights, row density, corner radius, zebra striping on tables |
| What is shown at all | top bar, side rail, sidebar, tabs, breadcrumbs, tenant switcher — and per screen type, the title, the action buttons, the row count |
| Your own stylesheet | for anything the fields do not reach. It loads after the tokens and wins on source order, so no rule needs !important |
Each field is named after the CSS property it writes — surface_2 writes --surface-2 — so your own stylesheet reaches a token without a lookup table. The shades derived from your accent color are generated for you, and you can still set any of them by hand.
Every setting applies per tenant and per user. Two tenants on one deployment look like two products. A screen inside an iframe declares its own frame — top bar, side rail, tabs — so an embedded screen is not the full application with parts hidden.
What is not a declaration
The engine, the gateways and the order the rules run in are ours, and the same for every customer. That is deliberate: determinism, ordering and the record must work the same way everywhere. If they were configurable, two deployments would end up disagreeing about what happened.