The loop that learns|INEMA.CLUB-PRO

Lesson 4 · 20 min

Lessons and rules: batch approval and review of an expired rule

The other side of the loop that learns is not a number: it is the lesson the agent draws from a mistake. Written straight into CLAUDE.md, it only grows, and nobody decides on it or reviews it. In this lesson you use SIL Loop R: occurrence, proposal, batch approval with an explicit decision, and automatic review when the rule's file changes.

Start the lesson
Open metal card file with cards organized by dividers and one pulled-out card with a yellow border.

In this lesson you will

  1. 1Occurrence, proposal and rule: three different things
  2. 2Approval batch: the agent proposes, the person decides
  3. 3Rule on trial with a date and a criterion
  4. 4Review by changed file, age and lack of use

Goal: record an occurrence and a proposal in SIL Loop R, approve in batch with an explicit decision, and reopen the rule when the watched file changes.

01The path of a lesson in SIL Loop R

sil.py 1.1.0, local SQLite in the project's .sil folder. No command sends a message or calls a model. Click each block.

Click each block in the diagram to see what it does.

Source: sil-loop-r/skills/sil-loop-r/SKILL.md and sil.py --help (v1.1.0, commit 63746bd, 10/05/2026).

02Rehearsal: two occurrences, one batch

Rehearsal project in /tmp. The j only prints the JSON fields that sil.py returns.

Terminal · cost-free rehearsal
SIL=~/projetos/sil-loop-r/sil.py   # git clone https://github.com/inematds/sil-loop-r ~/projetos/sil-loop-r
E=${TMPDIR:-/tmp}/ensaio-aprende/a4; rm -rf $E; mkdir -p $E/p; cd $E/p && git init -q
echo 'python3 -m http.server 8000' > serve.sh
s() { python3 $SIL --project $E/p "$@"; }
j() { python3 -c 'import json,sys; d=json.load(sys.stdin); print(*[k+"="+json.dumps(d.get(k),ensure_ascii=False) for k in sys.argv[1:]])' "$@"; }
s init | j version; s config --approval-batch 2 | j approval_batch
s occurrence --title "porta ocupada" --evidence "teste HTTP falhou: address already in use" \
  --cause "servidor de outra sessão na mesma porta" --correction "checar a porta antes" | j id
s lesson --occurrence O0001 --proposal "checar a porta antes de subir servidor" --scope "testes HTTP" --watch serve.sh | j id status
s occurrence --title "push no remoto errado" --evidence "git push foi para origin, não para o remoto da conta" | j id
s lesson --occurrence O0002 --proposal "conferir git remote -v antes do push" --scope "publicação" | j id status
echo "## fim da tarefa: chegou a hora do lote?"; s status | j approval_due approval_reasons
s request | j requested
Example from the repository
version="1.1.0"
approval_batch=2
id="O0001"
id="L0001" status="proposed"
id="O0002"
id="L0002" status="proposed"
## fim da tarefa: chegou a hora do lote?
approval_due=true approval_reasons=["lote de novas propostas"]
requested=true

With the batch set to 2, the second proposal turns on approval_due. From here on, the agent shows the person the ID, proposal, evidence, scope and suggested decision, and waits.

03Decide, and watch the rule go back to review

Continues the previous block. One proposal adopted, another on trial for 14 days; then the watched file changes.

Terminal · cost-free rehearsal
SIL=~/projetos/sil-loop-r/sil.py
E=${TMPDIR:-/tmp}/ensaio-aprende/a4; cd $E/p   # continua o bloco anterior
s() { python3 $SIL --project $E/p "$@"; }
j() { python3 -c 'import json,sys; d=json.load(sys.stdin); print(*[k+"="+json.dumps(d.get(k),ensure_ascii=False) for k in sys.argv[1:]])' "$@"; }
ATE=$(python3 -c 'import datetime; print(datetime.date.today() + datetime.timedelta(days=14))')
s decide L0001 adopt --approved-by "Seu Nome" --reason "falhou duas vezes; correção comprovada" | j status rule
s decide L0002 trial --until $ATE --criterion "nenhum push no remoto errado em 14 dias" \
  --approved-by "Seu Nome" --reason "uma ocorrência só" | j status
s check > /dev/null; echo "check: $?"
echo "## o arquivo vigiado mudou"; echo 'python3 -m http.server 8080' > serve.sh
s check | j reviews; s check > /dev/null; echo "check: $?"
s review R0001 keep --approved-by "Seu Nome" --reason "a porta mudou; a regra continua valendo" | j status
s check > /dev/null; echo "check: $?"
Example from the repository
status="adopted" rule="R0001"
status="trial"
check: 0
## o arquivo vigiado mudou
reviews=[{"id": "R0001", "reasons": ["arquivo alterado: serve.sh"]}]
check: 1
status="active"
check: 0

check exits 0 with nothing pending, 1 with something pending (here, the review) and 2 on error. Exit 0 does not prove the rules are true; only that nothing is overdue.

04Real case: this machine's lesson loop

INEMA uses LESSONS.md, FALHAS.md and LIMITES.md in the wifi project (the monitoring hub). Counts only; no line from the files appears here.

1. 05/10/2026

The sil-melhoramento/ANALISE.md analysis counted 37 lessons in wifi's CLAUDE.md, 101 lines in FALHAS.md and 255 in LIMITES.md, 49 still "aberto".

Its conclusion: 100% "prose" rung, no triage, no ID, no citation and no pruning. The lesson about a busy port had been written three times on different dates.

05Measure yours

Run it in your project folder. The script only counts lines and marks; it does not print content.

Terminal · in your project
K=~/projetos/loop-r-eng-aprende-v72/kit
cd ~/projetos/<your-project>   # the folder where your CLAUDE.md/AGENTS.md and your lessons live
python3 $K/contar-licoes.py .
Example from the repository
CLAUDE.md: 82 linhas, 19 lições na seção Lessons
AGENTS.md: 10 linhas, 0 lições na seção Lessons
LESSONS.md: 164 lições · 9 marcadas como repetidas · 0 com ID
FALHAS.md: 167 falhas · 90 prompt · 85 infra (as duas contam quando a linha diz as duas)
LIMITES.md: 424 limites · 115 ainda 'aberto'
SIL Loop R: não iniciado nesta pasta
degrau: prosa — sem decisão registrada, sem data de revisão, sem citação

The prompt and infra columns add up to more than the total because 8 lines say both.

06Practice

Rehearsal first, then your project.

E10 · The batch in the rehearsal

10 min

Run both rehearsal blocks.

Done when: the first shows approval_due=true and requested=true; the second ends with check: 0, check: 1 (after changing serve.sh) and check: 0.

E11 · Diagnosis of your lessons loop

10 min

Run contar-licoes.py in your project and note how many lessons exist, how many are repeated, and whether any has an ID or review date.

Done when: python3 $K/contar-licoes.py . prints the SIL Loop R: line and at least one count line.

E12 · Three real lessons in the SIL

30 min

Start the SIL in your project, take the three lessons that repeat the most, and record each one as occurrence + proposal, with --watch on the file the rule protects. When the batch kicks in, decide yourself, with a reason.

Done when: python3 $SIL --project . export | python3 -c 'import json,sys; print(len(json.load(sys.stdin)["rules"]))' → at least 1, and python3 $SIL --project . check; echo $? → 0.

07Lesson quiz

Question 1 of 5

The approval batch arrived and the person did not respond. What does the agent do?skill

08In three sentences

SeparateAn occurrence is the fact, a proposal is the lesson, a rule is the approved lesson; each one with an ID.
Decide in batchesThe agent proposes and prepares the batch; the person decides with a name and a reason; silence does not approve.
ReviewA changed file, age, or lack of use reopens the rule; check tells you when something is pending.

Going further

Previous lessonNext lesson