This starts chapter A1. Its course guide is A1 in the Function A course guide →
Not recorded yet. The lesson below is complete and runnable today — the video is added later without touching this page.
recordings/A1.0.mp4Map the architecture you are about to build, and mark where trust changes.
Alex has a working prototype: a model, a booking API, and a loop that joins them. It cancels the right flight four times out of five. The fifth time it cancels a different one, and there is no record of why it chose that booking, no way to stop it mid-run, and nothing to point at when somebody asks. The prototype is not the problem. The absence of everything around it is, and that absence is what this chapter fills in.
cybertravels/README.md is the picture you are about to make true on your own machine.What an agent is — software that plans, calls tools and acts on what it reads — and a map of the seven components you build across this chapter, with the edges where trust changes marked before any of them is written.
Security guidance handed to somebody who has never built an agent lands as a list of rules with no mechanism attached, and gets filed as paperwork.
Draw the seven components of the system you are about to build, and mark the edges where trust changes.
Edges marked as trust boundaries, against total edges. The second number is always larger, and the gap is the part worth arguing about.
Measure this
| what to measure | denominator or target |
|---|---|
| edges marked as a trust boundary | count, against total edges on the map |
WHAT YOU ARE ABOUT TO BUILD
traveller ─► ingress ─► orchestrator ─► agent runtime
│
┌───────────────────┼──────────────┐
▼ ▼ ▼
tools (MCP) memory peer agents
│ │ │
└──────── audit + spans ───────────┘
seven components · every later lesson names one of themThree verbs — plans, calls tools, acts on what it reads — and every one of them is both the reason an agent is useful and the reason it is dangerous.
Compare it to the thing it is not. A chatbot that is wrong says something wrong. An agent that is wrong does something wrong — it cancels a booking, moves money, writes a file. The output is not text any more; it is a consequence, and a consequence cannot be retracted by a better next answer.
Across this chapter you build CyberTravels: a corporate travel platform whose product is agentic. Not a diagram of one — the actual thing, running on your machine, which you will then spend the rest of the commons attacking, defending, detecting and governing.
Nine components — the same nine the skill below maps, named the same way, so the page and the run agree. Eight of them exist in CyberTravels and the ninth does not, which is information rather than an omission.
Each one has a lesson that builds it and a skill that checks it. That is the whole map of this chapter on one screen: read the row, and you know which lesson to open and which skill to run.
| component | the file you write | lesson | skill that checks it | blamed for later |
|---|---|---|---|---|
| ingress | ingress/chat.py | A1.2 | agent-code-surface-analyzer | every injection in Function B |
| orchestrator | orchestrator/router.py | A1.2 | agent-code-surface-analyzer | the place controls get added |
| agent runtime | runtime.py | A1.1 | agentic-harness-loop | the step everything hinges on |
| model | config.py | A1.1 | agentic-harness-loop | being trusted as a decision |
| tools | tools/*.py | A1.2 | agent-code-surface-analyzer | the blast radius |
| mcp servers | mcp/internal_server.py | A1.2 | agent-code-surface-analyzer | descriptions you approved once |
| knowledge | knowledge/retriever.py, memory.py | A1.5 | memory-scope-and-origin-audit | persistence |
| messaging | a2a/protocol.py | A1.6 | peer-message-propagation-trace | one injection becoming four |
| egress | nothing — it does not exist | none in A | none, and that is the finding | B3.7, which is about building it |
Two honest notes about that table, because a tidy nine-components-to-nine-skills mapping would be a lie. One skill covers four of the components, because they are all declared surface and a single audit reads all of it. And egress has no lesson and no skill here at all: you cannot check a component you never built, which is exactly why the map marks it absent and why B3.7 exists.
Identity and audit are not on that list because they are not boxes on this map — they are properties every edge carries, which is why A1.3 and A2.2 are their own lessons rather than components here.
This is the only function in the commons with no adversary in it. That is on purpose. You cannot threat-model a mechanism you have never seen work, and a reader handed "apply least privilege to your agent" before they have written a token exchange will apply it as a sentence in a document.
By the end of A2 you will have built every control the rest of the commons refers to. Function B then tells you, component by component, exactly how each one is bypassed.
The skill below is the same one B1.1 uses to audit an architecture. Here it is used the other way round — to design one. It takes a component list and marks the edges where trust changes, which is where every control in Function B will end up going.
Read what it does before you run it.
The skill — skills/architecture/agentic-architecture-map/SKILL.md
name: agentic-architecture-map
description: >-
Draw a vendor-neutral map of an agentic system — ingress, orchestrator, agent
runtime, model, tools and MCP, memory and knowledge, messaging, egress — and
mark the edges where trust changes. Use before naming any risk, because a risk
with no component is an argument.
allowed-tools: Read, Grep, GlobEvery disagreement about agentic security is really a disagreement about which system is being discussed. The map fixes that: nine components and the edges between them, drawn the same way every time, so a risk can be pinned to a box and a control can be pinned to an edge.
First. Before threat modelling, before writing a risk register, and before any conversation that contains the phrase "secure the agent".
1 — Place the nine components. Ingress, orchestrator, agent runtime, model, tools, MCP servers, memory and knowledge, agent-to-agent messaging, egress. Draw every one even if a system has only a stub of it — an absent box is a decision, not a gap in the diagram.
2 — Draw the edges as data flow, not as call direction. Where text goes is what matters; who initiated the call is an implementation detail that hides whether untrusted content reaches the model.
3 — Mark the trust level of each component. Which ones receive content from outside the boundary, and which ones hold authority. The edge from a lower trust level to a higher one is a boundary crossing, and there are always more of them than expected.
4 — Annotate each edge with what crosses it. User text, retrieved documents, tool results, peer messages, credentials. This is what turns the picture into something a threat model can walk.
5 — Name the components that do not exist yet. A system with no gateway and no messaging is a smaller map, and saying that explicitly stops a later conversation about controls for components nobody has.
Input — the fixture committed at the top of scripts/agentic_architecture_map.py. Edit it and re-run: the buckets, counts and verdicts below are derived from it, not hard-coded.
9 components, 8 present at CyberTravels
component trust authority present
agent runtime 2 yes yes
egress 3 yes NO
ingress 0 - yes
knowledge 0 - yes
mcp servers 1 yes yes
messaging 2 - yes
The run continues past this. test_skills.py executes the script on every build, with no model configured — so what CI proves is that it runs and refuses legibly, not that it prints these lines. The output above is a recorded run against a real model, and nothing re-diffs it: a model's answer is not reproducible, and this repository does not claim otherwise anywhere it can be checked.
{
"components": [{"name": "str", "present": true, "trust": 0, "holds_authority": false}],
"edges": [{"from": "str", "to": "str", "carries": ["str"], "boundary_crossing": false}],
"crossings": 0,
"absent": ["str"]
}
Three ways to do this lesson. Pick one. They run the same procedure against the same code — what changes is who drives it, and how much you see.
The agent reads the lesson, explains the idea, fetches the code, runs the check and answers your questions as you go. This is the one to take if you are here to learn.
Install it, once. From the folder you cloned. --all does every agent it finds on your machine:
python3 scripts/install_skills.py --all --lessons A1.0Then restart your agent and open it in that folder. On Windows, if python3 says Python was not found, use python instead.
Then pick a1-0-what-an-agent-is:
| agent | install just for this agent | start it |
|---|---|---|
| Claude Code | python3 scripts/install_skills.py --tool claude --lessons A1.0 | type /a1-0-what-an-agent-is |
| GitHub Copilot (VS Code) | python3 scripts/install_skills.py --tool copilot --lessons A1.0 | type /a1-0-what-an-agent-is in Chat |
| Cursor | python3 scripts/install_skills.py --tool cursor --lessons A1.0 | type / in Agent chat and search for it |
| Codex | python3 scripts/install_skills.py --tool agents --lessons A1.0 | type $a1-0-what-an-agent-is, or run /skills |
No agent, no conversation. The same lesson executes and prints the same readback. Take this one if you have no assistant, if you are reviewing rather than learning, or if you want the result without the teaching around it.
python3 scripts/lesson.py A1.0Neither of the above, and no model needed. The first command writes CyberTravels exactly as it stood at the end of this lesson; the second prints the diff — the lines this lesson added or changed, and nothing from any later one.
python3 scripts/checkpoint.py --at A1.0 --out work/cybertravels
python3 scripts/checkpoint.py --at A1.0 --diffOn Windows, type python wherever these say python3 — and use \ instead of / in the paths. Everything else is identical. A0.0 step 2 explains why.
Ways 1 and 2 need a model; way 3 does not. A signed-in Claude Code CLI needs no API key, and any OpenAI-compatible endpoint works too. With neither, the audit exits 2 and says so rather than inventing an answer. A0.0 sets this up.
Ways 1 and 2 both end with the same readback: What I did, What changed, The number and Read this next. A step that was skipped or refused is reported as exactly that, never as a pass.
If you did the last lesson’s challenge, expect this to stop. Most challenges ask you to edit the code, and ways 1 and 2 will not overwrite your edits: you get stopped, not a failure, with two options — --out for a fresh folder that keeps your work, or --force to discard it and start this lesson clean.
Nine components with eight marked present, the eleven edges between them, and the subset of those edges where trust changes — which is a smaller set than the edge count and is the only part worth arguing about. egress comes back absent: that is the fixture telling you the truth about CyberTravels, not a gap in the map.
Mark egress present in the fixture — change its third field from False to True — and re-run. The component count does not change, because the box was always on the map; what changes is which edges cross a boundary. Name the ones that move and the ones that do not, then read B3.7, which is the lesson about actually building it.
Tools used
Skill source: skills/architecture/agentic-architecture-map