Understand why the agent doesn’t change its own rules
An agent that rewrites its own rules may accidentally loosen exactly the rule that was holding it back. One line saying "you may pay small bills" and the module 4.1 policy no longer applies.
That's why the AGENTS.md from the kit says, explicitly: "You don’t change these rules. To propose a change, add a line to the 'Lessons' table in the runtime/POLITICA.md. The human approves."
🆕 New here? The four learning files
- Learning Table — at the end of the
runtime/POLITICA.md. Where the agent writes its proposals. - Lessons — section
## Lessonsof theAGENTS.md. Only rules you've approved, one per line. - FALHAS.md —
runtime/FALHAS.md. One line for each thing that broke. - LIMITES.md —
runtime/LIMITES.md. One line for each thing the environment wouldn't let you do.
How to read the diagram: the lower blue path always passes through the amber box, which is you. The upper red arc is the agent writing directly to Lessons without going through you. That's the shortcut that the AGENTS.md prohibits.
✓ The agent can
- ✓ Add a row to the Learning table
- ✓ Note the failure in
FALHAS.md - ✓ Note the block in
LIMITES.md - ✓ Suggest the lesson when you correct it
✗ The agent can’t
- ✗ Mark its own proposal as approved
- ✗ Write to Lessons without your approval
- ✗ Raise an action’s limit in POLITICA
- ✗ Delete a failure log entry that bothers you
the agent
you
becomes a Lesson
only change with your yes
Fill in the Learning table
The table is at the end of the runtime/POLITICA.md, under the heading “Learning (propose → approve → incorporate)”. It’s empty in the kit: just the heading, waiting for the first proposal.
Each line has four columns. The second asks for evidence: "I thought it was better" doesn't count; "this happened on this day, with this result" does.
O agente **não muda as próprias regras**. Ele acrescenta uma linha aqui; você decide. | data | o que aconteceu (com evidência) | proposta (1 linha) | status: proposto / aprovado / recusado | |---|---|---|---|
| date | what happened (with evidence) | proposal (1 line) | status |
|---|---|---|---|
| example | Clara asked for “available times tomorrow,” and the agent replied with today’s date; the response included times that were already booked | Before checking the calendar, repeat the date in AAAA-MM-DD and wait for confirmation | proposed |
| example | In the distributor’s report, the agent wrote “can I issue the invoice?” instead of leaving the invoice ready for Sônia | For payments, provide the finished text and a list of what to check; never offer to execute | proposed |
What to look for in the table: the two lines are examples of what it would look like, written for this course; they don’t come with the kit. Notice that the proposal fits on one line and says what to do, not how to feel.
proposed
The agent wrote it. No one has decided yet. Nothing changes in its behavior.
approved
You changed the status. The proposal goes to Lessons (topic 3) and takes effect.
rejected
It stays in the table. That way, the agent won’t suggest the same thing again next week.
💡 Don't delete the rejected item
The rejected line is memory. It shows the agent, and you three months from now, that the idea has already been considered and why it wasn’t included.
when it happened
the fact, not the opinion
one line
proposed / approved / rejected
Promote the approved item to Lessons
A POLITICA.md close the section like this: "Approved → becomes a rule in CLAUDE.md/AGENTS.md". In the kit, the place is the section ## Lessons of the AGENTS.md.
Why in the AGENTS.md and not in the CLAUDE.md? Because the CLAUDE.md from the kit starts by pulling the AGENTS.md. A rule written in one place applies to both Claude and Codex.
## Lessons Rules approved by the human, one per line:
@AGENTS.md ## Self-learning When the human corrects you, or you notice a mistake you made: propose the lesson as a row in the “Learning” table in `runtime/POLITICA.md`. Once approved, it goes into `## Lessons` in `AGENTS.md`.
🆕 New here? What the @AGENTS.md
In the CLAUDE.md, a line with @ and a filename asks Claude Code to read that file alongside it. Codex reads the AGENTS.md directly. Result: both agents read the same Lessons.
How to read the diagram: everything goes through the amber box. You write the rule once in the AGENTS.md, and both blue arrows point to the same rule for both agents. There’s no "Claude-only" version that can get out of date.
Example of what it would look like (not included in the kit)
If Clara approves the first proposal in topic 2, the end of the AGENTS.md looks like this:
## Lessons Rules approved by the human, one per line: - Before checking the calendar, repeat the date in YYYY-MM-DD format and wait for confirmation.
💡 Who writes the line in Lessons
It can be you, manually, or the agent, after your explicit request ("I approve line X; copy it to Lessons"). What matters is the order: first your yes, then the copy.
one rule per line
Claude reads along
same rules
corrected → proposes
Record each failure on one line
When something breaks and you fix it, the temptation is to move on. The runtime/FALHAS.md asks thirty seconds beforehand: one line with the date, what broke, the smallest fix, and whether the problem was with the prompt or infrastructure.
The kit already includes a real entry from when it was tested. It's the best example of the format:
| data | o que quebrou | menor correção | prompt \| infra | |---|---|---|---| | 2026-10-05 | `doctor.mjs` dizia "codex sem login" com o Codex logado | ler stdout **e** stderr (`codex login status` responde no stderr) | infra |
🆕 New here? stdout and stderr
Every terminal command has two text outputs: the normal one (stdout) and the warnings and errors one (stderr). On the screen, both appear together, but a program that reads only one of them misses the other. That’s what happened with doctor.mjs.
prompt
- ✓ The request led to the error
- ✓ The model misunderstood
- ✓ A limit was missing from the request
- ✓ Typical fix: add one sentence to the instructions
infrastructure
- ✓ Machine, network, login, software version
- ✓ Script that reads from the wrong place
- ✓ Service is down or slow
- ✓ Typical fix: add a safeguard (time limit, retry, check)
💡 Why just one line
After about ten lines, the pattern emerges on its own: “half are login infrastructure issues,” “every prompt failure is data.” Long text hides the pattern. If you need details, write them in another file and link to it in the line.
when it broke
the observed symptom
the missing safeguard
or both
Record what the environment blocked
Not every problem is a failure. Sometimes nothing broke: the environment simply didn’t allow it. The sandbox blocked the network, the tool doesn't have the feature, the site requires a login. This goes in the runtime/LIMITES.md.
In the kit, it comes with only the header. The last column, status, says whether the limit is still open or whether you’ve accepted living with it.
| data | o que tentei | o que barrou | contorno | status | |---|---|---|---|---|
| Situation | Goes to | Why |
|---|---|---|
O doctor.mjs read only one output and got it wrong | FALHAS.md | it was a defect, and it was fixed |
| The Codex sandbox blocks the network, including the local network | LIMITES.md | is an environment rule; recipe R1 says to note |
| You used reverse engineering in a test | LIMITES.md | the POLICY says: documented lab |
| You corrected the agent, and it learned | Learning table | it’s a rule change; it needs your approval |
What to look for in the table: the question that distinguishes them is "did it break, or was it blocked?" If it broke and you fixed it, FALHAS. If it was blocked, LIMITES. If the way of working changed, Aprendizado.
The example the kit itself provides
Recipe R1 warns: the Codex sandbox blocks network access. If a test needs to start a server, add the setting below to the bridge and note it in LIMITES.md:
-c sandbox_workspace_write.network_access=true
The line would record: what you tried (starting the test server), what blocked it (sandbox without network access), the workaround (this adjustment), and the status.
⚠️ A workaround isn’t a license
Opening the sandbox network is like loosening a fence. That's why it goes in a file you review. An undocumented workaround becomes, three months later, an open door no one remembers opening.
environment rule
what you did
open or accepted
also noted
Do the weekly review with the agent
The three files only help if someone reads them. Once a week, ask the agent to read everything and turn recurring themes into proposals. It does the tedious part. You do the part that matters: decide.
These are two requests. The first only generates proposals. The second, which you write after reading, approves whatever you want.
Open claude (or codex) in the project folder and paste:
Read runtime/FALHAS.md, runtime/LIMITES.md, and the Aprendizado table in runtime/POLITICA.md. Look for recurring issues or ones that are still open. For each case, add a row to the Aprendizado table with the date, evidence, a one-line proposal, and a proposed status. Do not mark anything as approved, and do not change AGENTS.md or CLAUDE.md. At the end, list the rows you added.
proposto. The section ## Lessons of the AGENTS.md stays the same.Na tabela Aprendizado de runtime/POLITICA.md, mude para aprovado a linha <data e proposta> e para recusado a linha <data e proposta>. Copie só a proposta aprovada, em uma linha, para ## Lessons do AGENTS.md.
The agent reads and proposes
First request. It cross-checks FALHAS, LIMITES, and the old proposals.
You read every line
Key question: does this rule loosen any POLITICA limit? If so, reject it.
You approve or reject
Second request, in your own words. Only what gets approved goes into Lessons.
Git records the change
Since everything is a text file, each new rule stays in the history with a date. You can see when and why it was added.
Quick test (optional): during review, the agent suggested "you can send reminders to patients without asking." What does Clara do?
a fixed time
proposals only
your decision
rules history
🎓 Module summary
Next module:
4.3 — Guard and dashboard