M9 · Safety, Ethics, and ComplianceM9-0323 min read
Lesson 50 of 58 · Module 10 of 10 · Week 6
Threads:The oversight threadThe NVIDIA stack thread
PII Masking, Agentic Security, and Audit Trails for Tool-Calling Agents
Three distinct controls, not one, govern what happens once an agent starts touching sensitive data and taking real-world actions: PII detection/masking blocks or masks sensitive data before processing, agentic security isolates authentication and authorization away from the LLM while validating every tool call at the execution rail, and an audit trail records what the agent did and why — and the exam's standing trap is putting credentials within the model's reach instead of keeping auth out of it entirely.
By the end you can
- 01State what PII detection and masking do, and at what point in the pipeline they intervene.
- 02Explain the specific agentic-security guidance to isolate authentication and authorization away from the LLM, and why that isolation matters even for a well-behaved model.
- 03Describe how execution rails (M9-01) validate a tool call, and what "validate" concretely checks.
- 04Explain what an audit trail records and why "what the agent did" is not, by itself, a complete audit record without "why."
Objectives 9.1 and 9.2: security, audit, and compliance guardrails
[GROUND TRUTH] (Sources/ncp-aai/domain-9-safety-ethics-compliance.md) groups objectives 9.1 and 9.2 as "system security, audit trails, and compliance guardrails (privacy, enterprise policy)." Unpacked, that pairing covers three separate mechanisms that happen to share a home in the same two objectives: detecting and masking sensitive data before it is processed, securing an agent's actions specifically (as opposed to securing its text outputs, which M9-01 and M9-02 already covered), and keeping a record of what happened that supports accountability after the fact. None of the three substitutes for either of the others — masking PII does nothing to stop an agent from making an unauthorized API call, validating a tool call does nothing to protect a customer's phone number sitting unmasked in a prompt, and neither protects anything unless there is a durable record of what actually happened when something goes wrong.
This module's guiding question asks for the specific control and where it runs. For this lesson's three mechanisms, "where it runs" spans a wider part of the pipeline than any single rail: PII masking runs wherever sensitive data first enters processing (which can be an input rail, a retrieval rail, or a preprocessing step ahead of either), agentic security concentrates specifically at the execution rail and in the architecture surrounding it, and audit trails run continuously, capturing the whole path rather than intervening at any one point in it.
Mechanism: three controls, each answering a different question
L1 — Intuition: data exposure, action authority, and accountability are three different failure modes
Imagine three separate incidents at the same company. In the first, a customer support transcript containing a full credit-card number gets forwarded, unredacted, into a training data export — nobody stole anything, but sensitive data traveled somewhere it should never have gone. In the second, an agent with access to an internal "issue refund" tool gets talked, through clever prompting, into issuing a refund far beyond any policy limit, to an account that was never verified as the requester's own — nothing was leaked, but an unauthorized action happened with real financial consequences. In the third, weeks later, nobody can reconstruct exactly which agent version, which tool call, and which upstream decision led to a disputed refund — there is no record precise enough to settle the question. Three different failures, three different root causes, and — critically for the exam — three different fixes. PII masking would have caught the first. Agentic security (specifically, tool-call validation and authorization isolated from the model) would have caught the second. An audit trail would have prevented the third from ever being unanswerable.
L2 — Mechanism: PII masking, agentic security, and the audit trail in turn
PII detection and masking. [VENDOR SPEC] (Sources/ncp-aai/domain-9-safety-ethics-compliance.md) names specific tooling for this: "PII detection/masking integrates GLiNER, Microsoft Presidio, Private AI, and others — blocking or masking sensitive data before processing." The mechanism is straightforward to state and easy to underestimate in practice: before a piece of text (a user message, a retrieved document, a tool's response) is handed to the LLM for reasoning, a detection pass scans it for personally identifiable information — names, phone numbers, addresses, account numbers, government identifiers — and either blocks the content outright or replaces the sensitive spans with placeholders before anything downstream ever sees the real values. Presidio, GLiNER, and Private AI are each independent tools built for exactly this detection-and-redaction task, and — echoing the layered-detection theme from M9-02 — a production deployment is not limited to picking exactly one; the same "don't rely on a single method" logic that governs content safety applies here too, because a named-entity detector tuned for one PII category (say, phone numbers) can miss another (say, a less-common national ID format) that a second, differently-trained tool catches.
Agentic security: isolating auth away from the LLM. This is where the domain's most specific piece of guidance lives, and it deserves to be stated in full rather than paraphrased away: [GROUND TRUTH] (Sources/ncp-aai/domain-9-safety-ethics-compliance.md) states that "Guardrails supports tool-call validation and execution rails on tool calls; guidance is to isolate authentication/authorization away from the LLM and to monitor agent behavior." Two separate mechanisms are named together here, and they are worth separating cleanly. First, tool-call validation via the execution rail (M9-01) checks a specific call's arguments, target, and context before that call is allowed to fire — is this refund amount within policy, does this order_id belong to the account making the request, is the tool being invoked the one that was actually intended. Second, and distinctly, the authentication and authorization decision itself — does this user, this session, this agent instance actually have the right to perform this action at all — is architected to live entirely outside the LLM's reach. The model never holds a credential, a session token, or an API key that would let it act with more authority than the execution layer explicitly grants it for that specific call. It can request an action; whether that request is actually authorized is decided by code the model cannot see, influence through prompting, or bypass through clever phrasing.
Audit trails. [GROUND TRUTH] (Sources/ncp-aai/domain-9-safety-ethics-compliance.md) states plainly that audit trails "record what the agent did and why, supporting accountability and compliance." The "why" clause is doing real work here and is the piece most likely to be implemented incompletely in practice: a log line recording that issue_refund(order_id=X, amount=85.00) executed at a given timestamp records what happened, but it does not, by itself, record why — what reasoning or retrieved context led the agent to decide a refund was warranted, what policy check the execution rail applied and what it found, and what (if anything) a human reviewer contributed if the case escalated. A complete audit trail links the action to the decision context that produced it, because "what happened" without "why it happened" is a record that can confirm an incident occurred but cannot explain it, diagnose it, or prevent its recurrence.
L3 — The exam-relevant edge case: a well-behaved model is not a security boundary
The trap this objective is built around is subtler than "don't give the model a password." A team can be scrupulously careful never to hard-code credentials into a system prompt and still violate the isolation principle, if the effective authority available to the model — through a tool it can call with broad, under-scoped permissions — exceeds what any single legitimate use case actually needs. If a "look up customer" tool the model can invoke also happens to have write access to the same customer record, the model does not need to be given a password for that write access to be a live risk; it only needs to be persuaded, through any prompt injection or multi-turn manipulation M9-02's jailbreak-protection material already covers, to call that tool in a way its designer never intended. The isolation principle is therefore not just "keep secrets out of the prompt" — it is "scope every tool's actual permissions to the narrowest capability the legitimate use case requires," so that even a fully successful manipulation of the model's behavior cannot translate into an action beyond what that specific tool was ever authorized to do, regardless of what the model believes it should do.
This is also why execution-rail validation and auth isolation are described together rather than as alternatives: validation catches a malformed or out-of-policy call (wrong amount, wrong target, wrong tool), while isolation ensures that even a call that somehow passes validation cannot exceed the authority the calling context actually holds, because that authority was never something the model's own reasoning controlled in the first place. Either mechanism alone leaves a gap the other closes.
Why "monitor agent behavior" is its own clause, not a restatement of validation
[GROUND TRUTH] (Sources/ncp-aai/domain-9-safety-ethics-compliance.md) pairs "isolate authentication/authorization away from the LLM" with a second, separate instruction: "monitor agent behavior." It is easy to read these as the same idea stated twice, but they cover different time horizons and different failure modes. Isolation and validation are point-in-time checks — they run once, at the moment a specific call is about to fire, and they either allow or block that one call. Monitoring is continuous and pattern-level: it is the practice of watching an agent's behavior across many calls, over time, for a shape that no single call's validation would ever flag on its own. A tool call for a 40 refund passes validation cleanly on its own merits; forty 40 refund calls from the same session in ten minutes, each individually valid, is a pattern a single-call validator has no mechanism to notice, because validation by design evaluates one call in isolation, the same limitation M9-01 identified in input rails versus dialog rails.
This is why agentic security, properly understood, is not fully discharged by "we validate every tool call." A deployment that validates every call correctly but has no monitoring layer watching the aggregate pattern of calls across a session, an account, or a time window is protected against a single malformed or unauthorized call and unprotected against a slow-drip pattern of individually-valid calls that, in aggregate, constitute abuse — a distinction with the same shape as the retry-versus-circuit-breaker distinction from M2-05: one mechanism evaluates a single instance, the other evaluates a pattern across many instances, and neither substitutes for the other.
⭐ THE EARNED INSIGHT: A model that has never been given a credential, never seen a password, and never been instructed to bypass a policy can still cause an unauthorized action, because the vulnerability the isolation principle defends against is not "the model was told a secret" — it is "the model's own conclusion about what should happen was allowed to double as the authority to make it happen." Tool-call validation and auth isolation exist because the model's conclusion and the system's actual grant of authority are supposed to be two separate facts, checked independently, and the moment a deployment lets the first stand in for the second, every persuasive conversation the model can be walked through becomes a live path to an action nobody with real authority ever approved.
The three controls side by side
| Control | Question it answers | Where it runs | Failure it catches |
|---|---|---|---|
| PII detection/masking | Is sensitive data about to enter processing unmasked? | Wherever sensitive data first enters the pipeline (input, retrieval, or preprocessing) | Sensitive data leaking into prompts, logs, training exports, or model outputs |
| Tool-call validation (execution rail) | Is this specific call's target and arguments within policy? | The execution rail, per M9-01 | A malformed, out-of-policy, or misdirected tool call |
| Auth/authz isolation | Does the calling context actually hold the authority for this action? | Architecture surrounding the execution rail, entirely outside the LLM | A model persuaded into requesting an action it was never authorized to take |
| Audit trail | What happened, and why? | Continuous, spanning the whole request path | An incident nobody can later reconstruct or explain |
Worked example: a tool call that fails validation before it ever reaches authorization
Consider an internal support agent equipped with a transfer_ownership(account_id, new_owner_email) tool, used legitimately when a business customer's point of contact changes. A user, mid-conversation, sends a message engineered to get the agent to transfer ownership of an account to an email address the user controls, framed as a routine contact update.
⚠️ UNVERIFIED (constructed scenario — the specific checks and outcome below are illustrative of how validation and authorization operate as separate gates, not a measured deployment trace):
1. Model reasoning concludes a transfer is warranted and emits:
transfer_ownership(account_id="ACC-4471", new_owner_email="user-controlled@example.com")
2. EXECUTION RAIL — tool-call validation runs first:
- Is "transfer_ownership" a tool this agent is configured to call at all? YES
- Does the account_id argument match a real, existing account? YES
- Is the new_owner_email argument a syntactically valid email? YES
→ Validation PASSES. The call is well-formed and on its face plausible.
3. AUTHORIZATION (isolated from the LLM, checked independently of anything
the model "believes" about the conversation):
- Does the SESSION making this request hold ownership-transfer authority
for ACC-4471 specifically? The session belongs to a general support
agent role, which the authorization service scopes to READ and to a
narrow set of low-risk WRITE actions (updating a phone number, a
shipping address) — ownership transfer requires a SEPARATE, elevated
role this session does not hold.
→ Authorization FAILS. The call is rejected before execution, regardless
of the model's confidence that the transfer was warranted.
4. AUDIT TRAIL entry recorded:
{
"action": "transfer_ownership", "account_id": "ACC-4471",
"requested_by_session": "support-role-8842",
"validation": "passed", "authorization": "denied",
"reason": "session lacks ownership-transfer role scope",
"model_reasoning_summary": "agent concluded transfer was a routine
contact update based on conversational framing",
"outcome": "call blocked, no side effect occurred",
"timestamp": "2026-08-02T14:22:03Z"
}
The call passed validation cleanly — every argument was well-formed and referred to a real account — which is exactly the point this scenario is built to make: validation checks the shape of a call, not whether the calling context is entitled to make it. Had authorization lived inside the model's own reasoning (a system-prompt instruction like "only transfer ownership with proper authorization," trusted to the model's judgment), the conversational framing that convinced the model a transfer was warranted might have been exactly persuasive enough to also convince it that authorization existed. Because authorization is architected entirely outside the model — a separate service checking the session's actual role scope, with no visibility into or dependence on what the model was persuaded to believe — the manipulation that succeeded against the model's reasoning failed completely against the authorization check, and the audit trail captured both facts: what the model concluded, and what the independent authorization layer decided, as two separate entries a reviewer can compare.
A second worked example: PII masking upstream of a tool call that never should have seen the raw value
Now consider a different agent, handling a customer's request to "check on my recent order and let the warehouse team know I'll need it re-shipped," where the conversation naturally includes the customer's full shipping address and phone number.
Raw user message (before any processing):
"My name is [customer name], phone [phone number], and I need order
#88213 re-shipped to my address at [full street address]."
PII DETECTION PASS (Presidio-style, runs before the message enters the
agent's context):
Detected: PERSON_NAME, PHONE_NUMBER, STREET_ADDRESS (3 entities)
Action: mask in place, log a mapping to a session-scoped vault the
fulfillment tool can query directly by order_id
Masked message the LLM actually reasons over:
"My name is [PERSON_NAME], phone [PHONE_NUMBER], and I need order
#88213 re-shipped to my address at [STREET_ADDRESS]."
Tool call the model emits:
reship_order(order_id="88213", reason="customer requested re-ship")
— note the tool call carries the order_id, not the raw PII; the
fulfillment system resolves the actual shipping address by looking up
order_id="88213" directly in its own system of record, never from
anything the model saw or passed along.
AUDIT TRAIL entry: records the tool call, the order_id, and a reference
to the PII-detection pass that ran — but never logs the raw PII values
themselves, only that masking occurred and which entity types were found.
The model never needed the customer's actual address or phone number to do its job correctly — it needed the order_id, and the fulfillment tool resolves the real shipping details from its own authoritative system, not from anything that passed through the model's context window. This is the practical shape PII masking takes in an agentic pipeline: not just "redact before showing a human," but "design the tool contract so the model's reasoning path never needs to carry the sensitive value at all," which is a stronger protection than masking-then-unmasking-just-in-time, because the raw value never has to re-enter anywhere the model could see it.
A third worked example: monitoring catches what per-call validation cannot
Extend the first worked example's support agent, now observed across a full shift rather than a single call. Each of the following refund requests, taken individually, passes both validation and authorization cleanly — the amounts are within the session's authorized ceiling, the order_ids are real, and the session genuinely holds refund authority up to that ceiling.
⚠️ UNVERIFIED (constructed scenario — illustrative of pattern-level monitoring, not a measured deployment log):
09:14 refund, order #71029, $42.00 -> validated, authorized, executed
09:19 refund, order #71104, $38.50 -> validated, authorized, executed
09:23 refund, order #71180, $45.00 -> validated, authorized, executed
09:27 refund, order #71241, $41.00 -> validated, authorized, executed
09:31 refund, order #71309, $39.75 -> validated, authorized, executed
... (continues at roughly the same rate and amount for the next 40 minutes)
MONITORING LAYER (operating on the aggregate, not any single call):
- Refund frequency for this session: 5x the session's trailing 30-day
average over the same time-of-day window.
- Refund amounts: unusually tightly clustered just under a $50 threshold
that happens to sit below this session's per-transaction review
trigger — a pattern consistent with deliberately staying under a
review threshold rather than a natural distribution of real refund
amounts.
-> FLAG raised for human review; session's refund authority
temporarily suspended pending review, even though every individual
call that already executed passed its own point-in-time validation
and authorization check.
No single call in this sequence would ever trip a per-call validator — each one, in isolation, is a perfectly ordinary, in-policy refund. It is the aggregate rate and the suspicious clustering just under a review threshold that a monitoring layer, evaluating the pattern across many calls rather than any one call, is positioned to catch. This is the concrete difference between "we validate every tool call" and "we monitor agent behavior" that the source material names as two separate pieces of guidance rather than one: validation is necessary and, on its own, insufficient against exactly this class of pattern-level abuse.
Why this material is on the NCP-AAI exam
Objectives 9.1 and 9.2 sit inside a 5%-weighted domain, but [GROUND TRUTH] (Sources/ncp-aai/domain-9-safety-ethics-compliance.md) flags the agentic-security guidance specifically in the domain's own scope note: "the agentic-security guidance to isolate auth from the LLM" is one of exactly three things the scope note says explicitly to know, alongside the five rail stages and Colang. That is a strong signal about where a disproportionate share of this domain's scenario questions concentrate. Expect a question that describes an agent successfully persuaded, through some form of manipulation, into requesting an action — and asks what specific architectural choice would have prevented that manipulation from becoming a real action. The correct answer isolates authorization from the model's own reasoning; a common wrong answer suggests a better system prompt, more careful phrasing, or additional model training, all of which address the model's judgment rather than the actual authority boundary the objective is testing.
A second recurring pattern pairs PII masking with a scenario about training data or logging — a case where sensitive data flows into a place it should never persist unmasked — and asks which control addresses it; the answer is PII detection/masking specifically, not a generic "guardrails" answer, because masking is the mechanism named for exactly this failure mode, distinct from content safety or topic control. A third pattern tests the audit-trail "why" clause directly: a scenario describes a logging system that records only actions taken, and asks what is missing — the answer is the decision context (what reasoning, what validation result, what authorization outcome) that explains why the action happened, not merely that it happened.
What "enterprise policy" adds beyond regulatory compliance
[GROUND TRUTH] (Sources/ncp-aai/domain-9-safety-ethics-compliance.md) names "compliance guardrails (privacy, enterprise policy)" as a single objective, and the "enterprise policy" half is worth separating from privacy regulation specifically, because they are not the same source of obligation and a system built only to satisfy one can still fail the other. Privacy regulation (data-protection law, sector-specific rules) sets a floor every deployment must clear regardless of what any individual company decides. Enterprise policy sits on top of that floor and is company-specific: an internal rule that no agent may ever transfer more than a stated amount without a second approval, or that a particular customer segment's data may never leave a particular region's infrastructure, is not something any external regulator mandates — it is a business's own risk tolerance, encoded as a control. A tool-call validator and an authorization layer built purely against regulatory minimums will pass every legal requirement and still violate a company's own internal policy, if that policy is stricter than the law requires, which it very often deliberately is. The practical implication is that "compliance guardrails" in this objective means configuring the execution rail and the authorization layer against both sources of obligation together — regulatory floor and enterprise ceiling — not treating "legally compliant" as the finish line.
Common mistakes about PII, agentic security, and audit trails
| Mistake | What actually goes wrong | Fix |
|---|---|---|
| Trusting the model's own judgment as the authorization boundary | A sufficiently persuasive prompt or multi-turn manipulation can talk a well-behaved model into requesting an action it should never request, and if authorization lives in the model's reasoning, that manipulation becomes a real action | Architect authentication and authorization entirely outside the LLM's reach, checked independently of anything the model believes |
| Validating a tool call's shape without checking the caller's actual authority | A well-formed, plausible-looking call (right tool, valid arguments) can still be one the calling session has no right to make | Run validation and authorization as two separate checks — one on the call's shape, one on the caller's actual scope |
| Passing raw PII through the model's context "just to be safe later" | Sensitive data sits in the model's context window, in logs, and potentially in outputs, for longer than the task actually required it to | Design tool contracts so raw PII resolves inside the tool itself (by an id or reference) rather than traveling through the model's reasoning path |
| Logging only the action, not the reasoning and validation outcome behind it | An incident review has a timestamp and an action but no way to reconstruct why it happened or whether the safeguards worked as designed | Log the decision context — model reasoning summary, validation result, authorization outcome — alongside every logged action |
| Relying on a single PII-detection tool for every entity type | A named-entity detector tuned for common categories (names, phone numbers) can miss less-common formats (certain national IDs, less-standard address formats) a differently-trained tool would catch | Layer PII-detection methods the same way M9-02 layers content-safety methods, rather than treating one tool as sufficient |
| Scoping a tool's permissions broadly "for flexibility" | Even a fully successful manipulation of the model's behavior can then exceed the narrow legitimate use case, because the tool's actual permissions were never scoped tightly to it | Scope every tool's real permissions to the narrowest capability its legitimate use case requires, independent of what the model is instructed to do |
Why isn't a well-written system prompt enough to keep an agent from misusing a tool?
Because a system prompt is an instruction the model interprets, and interpretation is exactly the layer that prompt injection, multi-turn manipulation, and simply model error can distort. A system prompt that says "only issue refunds under $100 with the customer's explicit prior authorization" is a request for the model to behave a certain way, not an enforced boundary — the model can still, under a sufficiently crafted conversation, conclude that a larger refund or an unauthorized one is warranted, and there is nothing in a text instruction that stops the model from acting on that conclusion if nothing outside the model checks the action before it executes. Execution-rail validation and auth isolation exist precisely because they check the actual call against actual policy and actual authority, independent of whatever the model was persuaded to believe about that policy or authority during the conversation.
How does an audit trail actually support compliance, as opposed to just debugging?
Debugging and compliance ask related but distinct questions of the same record, and a well-built audit trail has to serve both without being designed for only one. A debugging use of the audit trail asks "what happened in this specific incident, and what in the pipeline produced it" — a narrow, incident-scoped question a developer asks once, usually right after something has gone visibly wrong. A compliance use asks a broader, standing question: "across every action this agent has taken over some period, can we demonstrate that authorization was checked, that PII was handled according to policy, and that any escalated case received human review" — a question an auditor or a regulator asks not about one incident but about the system's behavior as a pattern, often long after any specific incident is forgotten.
The practical implication is that an audit trail built only to support debugging — verbose, ad hoc, scattered across whatever logging each component happened to already emit — is frequently useless for compliance, because compliance review needs the record to be structured consistently enough to query in aggregate ("show me every case where authorization was denied, across the last quarter") rather than read narratively one incident at a time. [GROUND TRUTH] (Sources/ncp-aai/domain-9-safety-ethics-compliance.md) names both purposes together — "supporting accountability and compliance" — which is a signal that the exam expects you to recognize an audit trail as infrastructure serving a standing regulatory and governance need, not merely a debugging convenience a team happens to have turned on.
This connects directly to the next lesson's subject: M9-05 covers the EU AI Act's Article 14 requirement for effective human oversight of high-risk systems, and an audit trail structured for compliance review — not just debugging — is one of the concrete artifacts that actually evidences that oversight happened, as opposed to merely claiming it did.
Does PII masking replace the need for content-safety and topic-control rails from the last lesson?
No — the three address entirely different risks. Content safety and topic control (M9-02) govern whether the content being generated or discussed is safe and in-policy; PII masking governs whether sensitive personal data specifically is exposed in the pipeline, regardless of whether the surrounding content is otherwise perfectly safe and on-topic. A perfectly safe, entirely on-topic response can still leak an unmasked phone number, and a response with no PII in it at all can still be unsafe or off-topic. A deployment needs both categories of control running, because passing one says nothing about whether the other has been satisfied.
Glossary recap: PII, agentic security, and audit trail terms this lesson introduced
| Term | One-line definition |
|---|---|
| PII detection/masking | Scanning for personally identifiable information and blocking or masking it before it enters processing |
| Agentic security | The set of practices securing an agent's actions specifically — tool-call validation plus authorization isolated from the LLM |
| Tool-call validation | An execution-rail check on a call's target and arguments before it fires |
| Auth/authz isolation | Architecting authentication and authorization entirely outside the LLM's reach, so the model can request but never itself grant an action's authority |
| Audit trail | A record of what an agent did and why, supporting accountability and compliance |
| Presidio / GLiNER / Private AI | Named tools for PII detection and masking |
Key takeaways on PII, agentic security, and audit trails
- Objectives 9.1 and 9.2 cover three distinct mechanisms: PII detection/masking, agentic security (tool-call validation plus auth isolation), and audit trails — none substitutes for the others.
- The domain's specific, named guidance is to isolate authentication and authorization away from the LLM — the model can request an action, but whether that action is authorized is decided entirely outside its reach.
- Tool-call validation (an execution rail,
M9-01) checks a call's shape and policy fit; authorization checks the caller's actual authority — these are two separate gates, and a call can pass one while failing the other. - A well-written system prompt is an instruction the model interprets, not an enforced boundary — it is not a substitute for validation or authorization architected outside the model.
- The strongest PII protection designs the tool contract so sensitive values resolve inside the tool by reference, never traveling through the model's own reasoning path.
- An audit trail's "why" — the reasoning, validation result, and authorization outcome behind an action — is as necessary as the "what," and is the piece most often implemented incompletely.
Everything in this lesson has assumed the underlying model's outputs are themselves reasonably fair and non-toxic to begin with — that assumption is exactly what the next lesson interrogates. Next: M9-04 covers mitigating bias and toxicity in agent outputs, and the key distinction it draws is that bias mitigation is a data- and training-level concern the guardrails and security controls in this and the prior two lessons were never designed to fix.