Lesson map
Lesson 12. Map, example, EX058.
flowchart TD
L["Split the row on '. '"] --> A{"Segment startswith ACTION:"}
A -->|Yes| C["A call, in every mode that parses"]
A -->|No| N{"Mode is none, and the folded segment startswith action:"}
N -->|Yes| C
N -->|No| Z["This segment adds nothing"]
The spaced mixed-case form is visible in one branch.
Logical drawing
defence=none exfil_calls=17/20 any_injected_call=20/20
defence=keyword exfil_calls=10/20 any_injected_call=10/20
Learning outcomes
After this chapter, you should be able to:
- Separate the capital-marker test from the fold-and-strip test.
- Say which mode alone takes the second test.
- 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.
Lesson table; scroll horizontally to read all columns →
| 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
Lesson table; scroll horizontally to read all columns →
| 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
.invalidname. 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?
Show marking criteria
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.