> ## Documentation Index
> Fetch the complete documentation index at: https://docs.finwatch.finance/llms.txt
> Use this file to discover all available pages before exploring further.

# Anatomy of a Rule

A FinWatch rule is a self-contained unit of logic defined in a single `.ws` file. It evaluates incoming transaction data against a set of conditions and, if those conditions are met, produces a **verdict**. A **verdict** is an actionable decision about the transaction's risk.

Every rule is composed of four structural components: `rule`, `description`, `when`, and `then`.

### 1.1 The Complete Structure

```go lines theme={null}
rule HighValueTransactionCheck {
    description "Flags any single transaction exceeding $10,000 for manual review."

    when amount > 10000

    then review
         score  0.7
         reason "Transaction amount exceeds $10,000 high-value threshold"
}
```

### 1.2 The `rule` Block

**Purpose:** The top-level declaration that names the rule and acts as the container for all its logic.

**Syntax:**

```shellscript theme={null}
rule <RuleName> { ... }
```

**Key Facts:**

* The `rule` keyword is **optional** but strongly recommended for readability. The parser will accept an identifier followed by `{` as a valid rule start.
* `<RuleName>` is an **identifier**, not a string. It must start with a letter or underscore, and can contain letters, digits, and underscores.
* There is **one rule per `.ws` file**. The parser reads a single rule from the input.
* The entire body of the rule is enclosed in curly braces `{ }`.

**Naming Conventions:**

* Use `PascalCase` or `PascalCase_With_Underscores`.
* The name should describe the fraud pattern or policy it enforces.
* Good: `HighValueTransactionCheck`, `SanctionedCountryCheck`, `BlockIfPreviousFailed`
* Bad: `rule1`, `test`, `myRule`

### 1.3 The `description` Clause

**Purpose:** A human-readable explanation of the rule's intent. This is your audit trail. When a regulator asks "why was this transaction blocked?", the description is your first line of defense.

**Syntax:**

```go theme={null}
description "<text>"
```

**Key Facts:**

* The value must be a double-quoted string.
* It is **optional** in the parser, but **mandatory in practice**. A rule without a description is a rule that will be misunderstood.
* Write for a non-technical audience: compliance officers, auditors, and future teammates.

**Examples:**

```go theme={null}
// Good: Explains the what, and implies the why.
description "Blocks transactions to countries on the OFAC sanctions list."

// Good: Specific about the threshold and the regulatory driver.
description "Flags any single transaction over $10,000 for AML reporting (BSA/CTR requirement)."

// Bad: Too vague to be useful.
description "Checks amount."
```

### 1.4 The `when` Clause

**Purpose:** The logical heart of the rule. It defines the conditions that must evaluate to `true` for the rule to fire.

**Syntax:**

```go theme={null}
when <condition>
 and <condition>
 or  <condition>
```

**Key Facts:**

* Contains one or more conditional expressions.
* Multiple conditions are joined by `and` or `or` logical operators.
* If the entire `when` clause evaluates to `true`, the `then` clause executes.
* If it evaluates to `false`, the rule silently passes — no verdict is produced.
* **A rule MUST have a `when` clause.** The parser will reject a rule without one.

### 1.5 The `then` Clause

**Purpose:** Defines the action taken when the `when` clause is satisfied.

**Syntax:**

```go theme={null}
then <verdict>
     score  <number>
     reason "<text>"
```

**Key Facts:**

* **A rule MUST have a `then` clause.** The parser will reject a rule without one.
* `score` and `reason` are optional. If omitted, `score` defaults to `0.0` and `reason` defaults to `"No reason provided"`.
* `score` and `reason` can appear in any order after the verdict.

### 1.6 Fully Annotated "Hello World" Example

```go lines theme={null}
rule DormantAccountActivity {
    // ─── DESCRIPTION ───────────────────────────────────────────────────────
    // Provides context for analysts and auditors.
    description "Unusual activity after long period of account dormancy."

    // ─── WHEN ──────────────────────────────────────────────────────────────
    // Two conditions joined by 'and'. BOTH must be true.
    // Condition 1: Access nested metadata via dot notation.
    // Condition 2: A simple numeric comparison on a top-level field.
    when metadata.days_since_last_transaction > 90
     and amount > 1000

    // ─── THEN ──────────────────────────────────────────────────────────────
    // Verdict: 'review' (send to a human analyst queue).
    // Score: 0.7 (high confidence this is suspicious).
    // Reason: A clear explanation for the analyst.
    then review
         score   0.7
         reason  "High-value transaction after extended account inactivity"
}
```
