# VisibilityCondition

**Kind:** Interface

**Source:** [`atloria-monorepo/apps/api/src/reader-access/visibility.util.ts`](https://github.com/sherkety/atloria/blob/main/atloria-monorepo/apps/api/src/reader-access/visibility.util.ts#L28)

D4 content segmentation — the ONE pure visibility evaluator.

A visibility rule is a JSON tree of attribute conditions over the reader's
canonical claims (`ReaderClaims.attrs`: role / plan / region / custom):

  { "allOf": [ <rule>, ... ] }                    — every child must pass
  { "anyOf": [ <rule>, ... ] }                    — at least one child must pass
  { "attr": "plan", "op": "eq",  "value": "pro" } — claim equals value
  { "attr": "role", "op": "in",  "value": ["admin","ops"] } — claim ∈ values
  { "attr": "plan", "op": "neq", "value": "free" }— claim present and ≠ value

Semantics (fail-closed by design):
 - null / undefined rule            → visible (public — no restriction)
 - missing claim                    → the condition FAILS (incl. `neq`)
 - claim values may be arrays       → eq/in match on intersection
 - allOf: []                        → true (vacuous)
 - anyOf: []                        → false (nothing can satisfy it)
 - malformed rule node              → false (a broken rule must never expose content)

Category rules CASCADE: a document's effective rule is its own rule ANDed
with every rule up its category ancestor chain (see composeRules).

## Properties

| Property | Type |
|---|---|
| `attr` | `string` |
| `op` | `'eq' | 'in' | 'neq'` |
| `value` | `string | number | boolean | Array<string | number | boolean>` |
