# SG/Sentinel Rule Architecture Strategy: Rules As A Fractal Graph

**version** v0.27.58
**date** 18 May 2026
**from** Human (project lead)
**to** Architect, Developer (lead), Security, AppSec, @Dev
**type** Arch / research brief

---

## What This Is

The twelfth brief in the SG/Sentinel series, going deep on the rule architecture itself, and triggering research on the rules, regexes, and strategies that already exist in open-source WAFs so we do not reinvent the wheel. Where the rules-engine brief established that rules are everything, this brief is about **how the rules are structured: as a fractal graph, with rich metadata, full traceability, and a spectrum from deterministic to opinion-based.**

The core architectural claim: **rules are fundamentally a graph, with a fractal structure.** Rules within rule sets; rule packs that activate only on a particular rule; rules that determine which rules to call next. This graph structure is essential for scalability, because it prevents the slowdown that comes from naively accumulating more and more rules into one flat list.

The brief covers the rule graph and its fractal structure, the rich metadata each rule carries, the IDs-everywhere traceability principle, the deterministic-to-opinion spectrum, the art-of-the-possible reduction that makes our rules easier, the rule categories to build, and the research into existing rules we should learn from rather than rebuild.

The voice memo was clear on the build approach: **start with simple rules, easy wins; let the agentic team write rules; learn from the existing open-source body of work.**

## Rules Are A Fractal Graph

The central structural principle: **rules are a graph, not a flat list, and the graph is fractal.**

A flat list of rules does not scale. Every request would have to be checked against every rule, and as the rule count grows, so does the per-request cost. The voice memo named this concern directly: **"we shouldn't have this massive slowdown or massive inefficiencies because we keep adding more and more rules to the platform."**

The graph structure solves this:

| Graph Property | What It Enables |
|----------------|-----------------|
| **Rules within rule sets** | Group related rules; evaluate a set as a unit |
| **Rule packs activated by a rule** | A whole pack only runs if a triggering rule fires; not every request pays for every pack |
| **Rules that select next rules** | A rule determines which rules to call next; the graph is traversed selectively |
| **Fractal nesting** | Rule sets contain rule sets; arbitrary depth; the same structure at every level |

The voice memo's framing: **"you can have rules within rule sets, you can have a massive rule pack that only gets activated on a particular rule."** This is the key to scalability. A request only triggers the rules relevant to it, by traversing the graph from a small set of entry rules, activating deeper packs only when a triggering condition is met. **The cost of a request is proportional to the rules it actually traverses, not to the total number of rules in the system.**

This is the same fractal pattern that runs through the whole platform (vault of vaults, tool of tools, TUI of TUIs). Here it is rule of rules. The voice memo named it: **"that sort of fractal element."** The graph can be arbitrarily deep, but any given request traverses only the relevant path.

### Rules That Determine Which Rules To Call Next

A specific and powerful capability the voice memo named: **a rule can define what other rules to call next.** This makes the rule graph a directed, traversable structure where the path through it is itself rule-driven.

The voice memo: **"a rule should be able to define what other rules can be called next. You can have a rule to determine which rules to call next."**

This is what makes the graph efficient and expressive. The entry rules are cheap and universal; based on what they find, they direct traversal to the relevant deeper rules. A request that looks like a static-page fetch traverses a short path; a request that looks suspicious gets directed into deeper analysis packs. **The graph routes each request through exactly the rules it needs, decided by the rules themselves.**

## Rich Rule Metadata

Each rule is not just logic; it carries rich metadata that connects it to the broader system. The voice memo named the metadata each rule should have:

| Metadata | Purpose |
|----------|---------|
| **Semantic graph** | The rule's place in the semantic knowledge graph |
| **Standard mapping** | Which compliance standard requirement this rule satisfies (the compliance brief) |
| **Attack-tree mapping** | Which MITRE ATT&CK technique / attack tree this rule prevents (the research brief) |
| **Interconnections** | Connections to other rules; what it relates to |
| **Next-rule connections** | Which rules can be called after this one |
| **Confidence / determinism** | How sure the rule is (the spectrum below) |
| **Layer / altitude** | Which layer this rule runs at (the execution-model brief) |
| **Data requirements** | What data the rule needs (per-rule least privilege, the rules-engine brief) |

This rich metadata is what makes the rule graph more than a decision tree. Each rule knows its place in the standards, the attack trees, the compliance posture, and the rule graph. The voice memo: **"each rule should have a semantic graph, should have a mapping to the standard, should have a mapping to the attack tree it is preventing, should have interconnections, should have connections to other rules."**

This connects the rule architecture to everything else in the series: the compliance graph (standard mapping), the research brief (attack-tree mapping), the evidence graph (semantic graph), and the execution model (layer/altitude). **A rule is a node in several overlapping graphs at once: the rule graph, the compliance graph, the attack-tree graph, and the semantic knowledge graph.**

## IDs Everywhere: Full Traceability

A principle the voice memo flagged as critical and not fully covered before: **IDs everywhere, with clear traceability on everything that happens.**

The voice memo: **"it's critical that we have IDs everywhere, and we have very clear traceability on everything that happens. As soon as we can, we slap an ID."**

The mechanism: as soon as a request arrives, it gets an ID (we may get a request ID from AWS, but we provide our own as well). That ID tracks the request through its entire lifecycle: every rule it traverses, every decision made, every piece of evidence accumulated, over time.

| Traceability Need | What The ID Enables |
|-------------------|---------------------|
| Lifecycle tracking | Follow a request through every rule and decision |
| Historical analysis | What have we seen from this ID over time |
| Clean-up | Identify and remove what is no longer needed |
| Visualisation | Show the request's journey through the rule graph |
| Logging | Every log entry tied to an ID |
| Evidence linking | Evidence-graph entries tied to the request ID |

The voice memo: **"that's the ID that we can use to track the lifecycle, including over time. How much stuff have we seen, how much are we doing, and how can we clean up and really trace and visualise and log everything?"**

This connects to the evidence graph (the developer-friendliness brief) and the observability work. The ID is the thread that ties a request's entire journey together: the rules it hit, the decisions made, the evidence accumulated, the timeline it traversed. **Traceability via universal IDs is what makes the whole system debuggable, auditable, and visualisable.**

## Every Layer Has Rules; Same Architecture Everywhere

A consistency principle the voice memo reinforced: **every layer has rules, and the rule architecture is the same everywhere.** From the layer with almost no information (Layer 1, just a bit of the request) to the deeper layers with full access and async LLM capability, they all run rules, and the rules all follow the same architecture.

The voice memo: **"every layer that we have has rules. The whole rule architecture is the same everywhere, so every layer, from the one that has access to no information to the one that goes next level, they all run rules."**

The job of each rule, at every layer: **make decisions, do analysis, and make the next rules more effective.** This is the "make the next layers more effective" principle from the time brief, expressed at the rule level. Each rule does its part and improves the conditions for the rules that follow.

The voice memo: **"the job of each rule is to make decisions, or to make some analysis, and to make the next rules more effective. So we can move the action of the rules at the right altitude."** This is the horses-for-courses / right-altitude principle (from the codebase-extension brief) applied to rule placement: each rule runs at the altitude where it is most effective, and the uniform architecture means rules can move between altitudes as understanding evolves.

## The Art-Of-The-Possible Reduction

A point the voice memo made that dramatically simplifies our rules: **because most of our requests are for encrypted objects, and some of our sites are pure static pages, the space of valid requests is dramatically reduced, which makes invalid requests obvious.**

The voice memo: **"most of our requests are for objects and encrypted data, so we dramatically reduce the art of the possible. Some websites are just pure static pages, so we dramatically reduce what's actually available."**

This is a major advantage for rule simplicity. A general-purpose WAF has to handle the full space of possible web requests because it does not know what the application accepts. SG/Sentinel, protecting platforms where most requests are for encrypted objects or static pages, has a tiny space of valid requests. **The smaller the valid space, the easier it is to detect the invalid: anything outside the small known-good set is suspect.**

This connects to the no-invalid-request principle (the execution-model brief) and the coupling principle. The art-of-the-possible reduction is why those principles are tractable here: when valid traffic is a small, well-defined set (fetch this encrypted object, serve this static page), the allowlist is small and the detection of anything outside it is easy. The voice memo's example: **a request for `/etc/passwd` is never valid; a request for a PHP page on a static site is never valid.** These are trivial to block because the valid space is so constrained.

## The Deterministic-To-Opinion Spectrum

The voice memo described a spectrum of rule confidence, from fully deterministic to opinion-based: **a rule can be deterministic, non-deterministic, or have an opinion with a confidence level.**

| Rule Confidence | Example | Action |
|-----------------|---------|--------|
| **Deterministic, certain** | Request for `/etc/passwd`; never valid | Block immediately |
| **Deterministic, high-confidence** | Request for a PHP page on a static site | Block |
| **Opinion, fairly confident** | This pattern looks like a scan | Flag; maybe challenge |
| **Opinion, uncertain** | This is slightly unusual | Log; send to async analysis |
| **Non-deterministic / LLM** | Ambiguous; needs interpretation | Async LLM analysis |

The voice memo: **"a rule can be deterministic, can be non-deterministic, a rule can have an opinion. A rule can be 'I'm pretty sure of this, I'm very comfortable that this is exactly what is not supposed to happen' (somebody does a `/etc/passwd`, come on)."**

The deterministic, certain rules are the easy wins: fast, confident, block immediately. The opinion-based rules carry confidence levels and feed into the anomaly-scoring style of decision (see the research below). The non-deterministic / LLM rules are the async interpretation layer. **The spectrum lets each rule express how sure it is, and the engine combines confidences rather than treating every rule as a binary verdict.**

This connects to balancing false positives and false negatives. Deterministic-certain rules have near-zero false positives. Opinion rules trade off: more aggressive opinions catch more attacks but risk more false positives. The confidence spectrum is how we tune this per rule, and the anomaly-scoring model (from the research) is how we combine them.

## Rule Categories To Build

The voice memo named many rule categories. Organising them:

| Category | Examples |
|----------|----------|
| **Logging** | Capture traffic; the first rules; pure observation |
| **Easy-win security** | Block `/etc/passwd`, PHP-page scans on static sites, known exploit probes, phishing scans |
| **Security headers** | Add/enforce security headers |
| **Bot detection** | Detect bots; distinguish Google and wanted indexers from unwanted ones; decide what to do |
| **Detection** | Identify suspicious patterns |
| **Response** | What to return for a given decision |
| **Reaction** | Active responses to threats |
| **Evasion / deception** | Send bots on wild goose chases; drop connections; tarpit |
| **Performance** | Caching decisions, routing for speed |
| **Logistics** | Operational rules |

The voice memo's build order: **start with logging rules (pure observation), then easy-win security (the obvious blocks), then security headers and bot detection, then build out detection, response, reaction, and evasion.** The easy wins come first because they are high-value and low-risk: blocking a `/etc/passwd` request or a PHP-scan on a static site is unambiguous and immediately valuable.

## Research: Learning From Existing WAF Rules

The voice memo asked for research into the rules, regexes, formulas, and strategies that already exist, so we learn rather than reinvent. The research surfaces a clear body of work to draw on.

### The Anomaly-Scoring Model

The most valuable pattern from the research: **the OWASP CRS anomaly-scoring model.** Rather than blocking on the first matched rule, CRS accumulates a threat score across multiple rules; if the total exceeds a threshold (default 5), the request is blocked. This lets multiple low-confidence indicators combine into a high-confidence decision.

This maps directly onto our deterministic-to-opinion spectrum. Our opinion-based rules carry confidence; the anomaly-scoring model is how we combine them. A single "slightly unusual" rule does not block, but several together cross the threshold. **The anomaly-scoring model is the proven mechanism for combining our opinion rules, and we should adopt it.**

### Paranoia Levels

CRS organises rules into four paranoia levels (PL1-PL4), letting operators tune detection aggressiveness against false-positive rates. PL1 suits most applications; higher levels add regex-based SQL/XSS protections and cover less common attacks at the cost of more false positives.

This maps onto our progressive-lock-down model (the delegation brief). Our progression from permissive to minimal is the same idea as moving up paranoia levels. **We can adopt the paranoia-level concept directly: start at a low level (few false positives), increase as we tune.**

### Attack Categories

The research confirms the standard attack categories every WAF rule set covers: **SQL injection, cross-site scripting (XSS), local/remote file inclusion (LFI/RFI), remote code execution (RCE), command injection, HTTP protocol violations, scanner/bot detection, and session fixation.** These are the categories our security rules must cover, and the CRS provides battle-tested detection patterns for each.

### Rule Groups

The research shows mature WAFs organise rules into groups (Azure's DRS has 18 rule groups; each contains multiple rules; behaviour is customisable per rule, group, or whole set). This validates our fractal-graph approach: rule groups are the established pattern, and our rule-sets-within-rule-sets is the same idea taken further.

### The Adversarial-Evasion Caveat

An important finding: research has shown that **ModSecurity and CRS can be evaded with simple manipulations of attack queries** (adversarial machine learning against WAFs). This is a caution: regex-based rules alone are evadable. It validates our LLM-interpretation layer (the rules-engine brief): the deterministic regex rules handle the common case, but the async LLM analysis catches the obfuscated and adversarial attacks that evade regex. **Our edge over pure-CRS WAFs is the app-coupling (we know what good looks like) and the LLM interpretation (we catch what regex misses).**

### What To Reuse Versus Build

| Reuse From Open Source | Build Ourselves |
|------------------------|------------------|
| CRS attack-detection patterns (SQLi, XSS, etc.) | App-coupled rules (we know our valid traffic) |
| The anomaly-scoring model | LLM-interpretation rules (catch evasion) |
| Paranoia-level tuning concept | The fractal rule graph |
| Standard attack categories | The rich metadata (standard/attack-tree/semantic mappings) |
| Existing regexes and detection formulas | The IDs-everywhere traceability |

The principle: **reuse the generic detection patterns (decades of community work); build the differentiation (app-coupling, LLM interpretation, the graph, the metadata, the traceability).** This is the de-commoditising strategy applied to rules.

## How This Composes With The Series

| Brief | Relationship |
|-------|--------------|
| Rules-engine brief | Established rules-are-everything; this brief is how they are structured |
| Research brief | The attack-tree and standards mappings each rule carries |
| Compliance brief | The standard mappings each rule carries |
| Developer-friendliness brief | The semantic graph and evidence the rules connect to |
| Execution-model brief | The layers/altitudes rules run at |
| Time brief | The make-next-rules-more-effective principle |
| **This rule-architecture brief** | **The fractal graph structure, metadata, traceability, and confidence spectrum of the rules** |

## What This Asks For

Concrete next steps:

1. **Build the fractal rule graph** (rules within rule sets; rule packs activated by triggers; rules that select next rules).
2. **Define the rich rule metadata schema** (semantic, standard, attack-tree, interconnections, confidence, layer, data needs).
3. **Implement IDs everywhere** (our own request ID; full lifecycle traceability).
4. **Adopt the anomaly-scoring model** (combine opinion rules by accumulated score).
5. **Adopt the paranoia-level concept** (tune aggressiveness; maps to progressive lock-down).
6. **Build the easy-win rules first** (logging, then `/etc/passwd`-style blocks, security headers, bot detection).
7. **Reuse CRS detection patterns** for the standard attack categories.
8. **Build the LLM-interpretation rules** for the evasion-resistant layer.
9. **Implement the deterministic-to-opinion confidence spectrum** per rule.
10. **Have the agentic team write rules** (the LLM-assisted rule development from the rules-engine brief).
11. **Map short / medium / long-term rule roadmap** (which rules now, which later).

Estimated effort: the fractal graph and metadata schema are the foundational build (weeks); the easy-win rules are quick; reusing CRS patterns accelerates the security rules; the LLM-interpretation rules build on the async layer.

## What This Does Not Try To Be

Deliberate scope limits:

- **Not a flat rule list.** The graph structure is essential for scalability.
- **Not a CRS clone.** We reuse CRS patterns; we do not rebuild CRS.
- **Not regex-only.** Regex rules are evadable; the LLM layer catches what they miss.
- **Not all categories at once.** Easy wins first; build out over time.
- **Not binary verdicts only.** The confidence spectrum and anomaly scoring combine partial signals.

## Honest Risks

Three risks:

**Risk 1: The rule graph could become hard to reason about.** A complex graph of rules calling rules could be hard to understand and debug. Mitigation: the rich metadata and IDs-everywhere traceability make the graph inspectable; visualisation via the TUI; the agentic team and architect agent maintain coherence.

**Risk 2: Reused CRS patterns carry CRS's evadability.** If we lean on regex rules, we inherit their adversarial weakness. Mitigation: the LLM-interpretation layer; the app-coupling (we know valid traffic, so evasion of generic rules still hits our allowlist); do not rely on regex alone.

**Risk 3: The confidence spectrum and anomaly scoring need careful tuning.** Get the thresholds wrong and either false positives or false negatives spike. Mitigation: start permissive (low paranoia); observe-mode; tune from real traffic; the progressive lock-down discipline.

## Open Questions

| Question | Notes |
|----------|-------|
| Graph representation: how are rule-to-rule connections stored? | Part of the rule metadata; a directed graph |
| Anomaly-scoring threshold? | Start with a CRS-like default; tune from traffic |
| Which paranoia level to start at? | Low (PL1-equivalent); few false positives |
| How much CRS to import directly versus adapt? | The well-understood patterns; adapt to our metadata model |
| ID scheme: format and scope? | Our own ID plus AWS request ID; globally unique |
| How are rule packs triggered? | A triggering rule activates a pack; defined in the graph |
| How do agents write rules safely? | The dev/main/prod phases; AppSec review; testing |
| Short/medium/long-term rule roadmap? | Easy wins now; CRS-pattern security next; LLM-interpretation and app-coupled later |

## Relationship To Previous Briefs

| Date | Document | Relationship |
|---|---|---|
| 18 May | `v0.27.58__arch-brief__sg-sentinel-compliance-as-living-graph.md` | The standard mappings each rule carries |
| 18 May | `v0.27.58__research-brief__sentinel-learning-from-standards-and-services.md` | The attack-tree mappings and CRS/Coraza patterns this reuses |
| 18 May | `v0.27.58__arch-brief__sg-sentinel-developer-friendliness-and-evidence-graph.md` | The semantic graph and evidence the rules connect to |
| 18 May | `v0.27.58__arch-brief__sg-sentinel-time-as-first-class-dimension.md` | The make-next-rules-more-effective principle |
| 18 May | `v0.27.58__arch-brief__sg-sentinel-rules-engine.md` | Established rules-are-everything; this is how they are structured |
| 18 May | `v0.27.58__arch-brief__edge-layer-execution-model-layered-responders.md` | The layers/altitudes rules run at |
| 18 May | `v0.27.58__arch-brief__edge-security-and-logging-layer-principles.md` | The make-the-site-hostile easy-win rules |
| 17 May | `v0.27.55__strategy-brief__myfeeds-b2b-research-briefings-as-evidence-packs.md` | The semantic-graph pattern the rule metadata uses |
| 16 May | `v0.27.45__strategy-brief__appsec-mini-tools-on-top-of-vaults.md` | The AppSec rule-writing ecosystem |

---

## Acceptance Criteria

| # | Criterion | Verification |
|---|-----------|-------------|
| 1 | The fractal rule graph works (rules within sets; packs; next-rule selection) | Graph traversal is selective |
| 2 | Request cost is proportional to rules traversed, not total rules | Scalability verified |
| 3 | Each rule carries rich metadata (semantic, standard, attack-tree, etc.) | Metadata schema populated |
| 4 | IDs everywhere; full lifecycle traceability | Every request traceable end to end |
| 5 | The anomaly-scoring model combines opinion rules | Accumulated-score blocking works |
| 6 | The paranoia-level concept tunes aggressiveness | Levels map to progressive lock-down |
| 7 | Easy-win rules work (logging, /etc/passwd blocks, headers, bots) | Obvious bad traffic blocked |
| 8 | CRS detection patterns reused for standard attack categories | SQLi, XSS, etc. covered |
| 9 | LLM-interpretation rules catch evasion | Adversarial attacks that evade regex are caught |
| 10 | The deterministic-to-opinion confidence spectrum works per rule | Rules express confidence |
| 11 | The agentic team writes rules | LLM-assisted rule development operates |
| 12 | A short/medium/long-term rule roadmap exists | Rule build is planned |

---

This document is released under the Creative Commons Attribution 4.0 International licence (CC BY 4.0).
