diff --git a/concepts/evaluators/built-in-evaluators.mdx b/concepts/evaluators/built-in-evaluators.mdx
index e8bccd0..3dc7cba 100644
--- a/concepts/evaluators/built-in-evaluators.mdx
+++ b/concepts/evaluators/built-in-evaluators.mdx
@@ -79,13 +79,17 @@ Flexible value matching with multiple modes and logic options.
| `values` | list | required | Values to match against |
| `logic` | string | `"any"` | `"any"` = match any value, `"all"` = match all |
| `match_on` | string | `"match"` | `"match"` = trigger when found, `"no_match"` = trigger when NOT found |
-| `match_mode` | string | `"exact"` | `"exact"` = full string match, `"contains"` = word-boundary match |
+| `match_mode` | string | `"exact"` | `"exact"` = full string match, `"contains"` = word-boundary match, `"starts_with"` = prefix match, `"ends_with"` = suffix match |
| `case_sensitive` | bool | `false` | Case sensitivity |
`match_mode="contains"` uses word-boundary matching, not generic substring matching. For example, `"admin"` will match `"admin user"` but will NOT match `"sysadministrator"`.
+
+`match_mode="starts_with"` and `match_mode="ends_with"` use literal string prefix/suffix matching. They are not path-boundary aware, so `"/safe"` will also match `"/safezone"` when using `starts_with`.
+
+
```json
@@ -110,6 +114,27 @@ Flexible value matching with multiple modes and logic options.
}
}
+// Allowlist: only permit writes under approved prefixes
+{
+ "name": "list",
+ "config": {
+ "values": ["/workspace/", "/tmp/scratch/"],
+ "match_on": "no_match",
+ "match_mode": "starts_with",
+ "logic": "any"
+ }
+}
+
+// Block file types by suffix
+{
+ "name": "list",
+ "config": {
+ "values": [".env", ".pem", ".key"],
+ "match_mode": "ends_with",
+ "logic": "any"
+ }
+}
+
// Allowlist: only permit specific tools
{
"name": "list",