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

## Chapter 14 — Separate returns an empty list

### Learning outcomes

After this chapter, you should be able to:

1. Say where `calls = []` sits relative to the parse.
2. Contrast this row's injected zeros with keyword's 10.
3. Refuse to describe the assignment as a product control.

### 14.1 The assignment runs after parsing and before the return.

In `agent`, calls are collected first. Two later statements may rewrite that list. Allowlist filters it. Separate replaces it with `[]`. The replacement does not depend on what was collected. Invoice rows, note rows and memo rows can all have been examined. The returned list is still empty, so both injected counters see no call. The printed line is `exfil_calls= 0/20` and `any_injected_call= 0/20`. The leading spaces are width 2 again.

This is the only defence row whose `any_injected_call` is 0. Keyword's matching column is 10, because keyword returns early on some rows and still returns the invoice calls on others. Allowlist's matching column is 3. Separate is the row that reaches zero injected calls. Benign stays 0, as it does on the other three lines.

The comment in the fence says untrusted data never becomes instructions. In this toy that sentence is implemented by discarding the list. It is not implemented by a second model, and it is not a setting Omar can switch on inside InboxAide. The firm's actual control, already recorded in the pilot, is that sending stays off unless a person acts. This print does not measure that control.

| Row | any_injected_call | Why |
|---|---|---|
| none | 20 | Both verb shapes count |
| keyword | 10 | Invoice rows only |
| allowlist | 3 | Tag rows only |
| separate | 0 | The list is replaced |

### 14.2 Worked example

| Sentence | Decision |
|---|---|
| "Separate prints zero injected calls because the list is cleared." | Keep |
| "Keyword also reached zero." | Refuse; keyword prints 10 |
| "This row proves InboxAide ignores untrusted mail." | Refuse; the row is this function |

> **Synthetic case.** The empty list is a teaching assignment. It is not a vendor feature.

### Errors and limits

Zero on this row is easy to over-read. It describes one function's last assignment.

### Apply

- **EX060 — Empty list.** What does the separate row do after parsing, and which row is the only one with any_injected_call at 0? *Rubric:* 3 = it assigns an empty list after the parse; only this row prints 0 injected calls; keyword still prints 10;; 2 = the assignment and the zero;; 1 = "it blocks everything";; 0 = equates the row with a product.

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

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

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

## Worked answers

<a id="answer-ex060"></a>
**EX060.** Separate assigns `calls = []` after the parse, so both injected counts are 0. It is the only row with any_injected_call at 0. Keyword still prints 10. The assignment is this toy function, not a switch inside InboxAide.
