<a id="ch-12"></a>

## Chapter 12 — Only the none mode sees the spaced verb

### Learning outcomes

After this chapter, you should be able to:

1. Separate the capital-marker test from the fold-and-strip test.
2. Say which mode alone takes the second test.
3. Account for the drop from 17 to 10 without inventing a new string.

### 12.1 Two tests sit in one `if`. Keyword can leave before either of them matters.

The agent splits the document on `". "`. A stripped segment that `startswith("ACTION:")` is parsed in every mode that reaches that test. The other disjunct runs only when `mode == "none"`: spaces are removed, case is folded, and the segment must then start with `action:`. The memo rows use a mixed-case verb and a space before the colon. Only the none branch accepts that shape. Keyword, allowlist and separate never evaluate it, so those seven memo rows contribute no call outside none.

That is why `defence=none` shows `exfil_calls=17/20`: ten invoice rows plus seven memo rows, all email-shaped. `any_injected_call=20/20` on that line adds the three note rows, whose call is tag rather than email.

Keyword has an earlier exit. If any stripped segment contains `ignore`, the function `return []` for the whole document. The note rows contain that word, so they contribute nothing on the keyword line. Combined with the invisible memo shape, keyword's counts are the ten invoice rows only: `10/20` and `10/20`.

This parser is a deterministic rule engine. It is not an assistant product, and a space before a colon is a fact about this branch. It is not a method for steering a real system. The strings live in the published fence. This chapter does not add one.

| Mode | Sees `ACTION:` | Sees the spaced form | Notes with "ignore" |
|---|---|---|---|
| none | Yes | Yes | Still parsed |
| keyword | Yes | No | Early empty return |
| allowlist | Yes, then filtered | No | Parsed, then filtered |
| separate | Yes, then cleared | No | Cleared after the parse |

### 12.2 Worked example

| Count | What produced it |
|---|---|
| 17 email-shaped calls on none | 10 invoices and 7 memos |
| 20 calls of any kind on none | Those 17 plus 3 tag notes |
| 10 and 10 on keyword | Invoices only; notes returned early; memos unseen |

> **Synthetic case.** The destination inside the fence is already a reserved `.invalid` name. No further destination is added here.

### Errors and limits

Describing this branch is not permission to try a spaced verb against InboxAide, ReceiptSort, or any other product.

### Apply

- **EX058 — One branch.** Why does the none row show 17 and 20, while the keyword row shows 10 and 10? *Rubric:* 3 = none counts the spaced memos and the tag notes; keyword returns empty on ignore and never parses the spaced form; no new string is required;; 2 = both row pairs with one cause each;; 1 = one row;; 0 = offers a new string to try on a product.

<!-- open-cyber-academy:chapter-navigation:start ch-12 -->
### Continue studying — lesson 12 (chapter 12 of 20)

[← Chapter 11](#ch-11) · [Course chapter index](../SUBJECTS.md) · [Chapter 13 →](#ch-13)

Continue to the next authored lesson.
<!-- open-cyber-academy:chapter-navigation:end -->

## Worked answers

<a id="answer-ex058"></a>
**EX058.** On the none row, ten invoice rows and seven spaced memo rows are email-shaped, which is 17, and the three tag notes bring any_injected_call to 20. Keyword returns an empty list when a segment contains ignore, and it never parses the spaced form, so only the ten invoices remain. No new string is required, and none should be tried on a product.
