MODULE 2.5

✅ Readback: prove it in a fresh session

You built the portable core and ported the skill. Now comes the only question that matters: can an agent that has never seen the project pick it up? In this module you run the readback on both runtimes, read the answer critically, and learn to mark each check as passed, failed or not run.

6
Topics
~30
Minutes
Intermed.
Level
Practice
Type
1

❓ The 5 readback questions

Readback is a continuity test: you open a fresh session, with no history, and ask the agent to read the project and answer five questions. If it answers by citing the right files, the portable core works. If it makes things up, or answers from its own generic knowledge, the core exists but isn't being used.

1 · goal + definition of done 2 · one rule + source file 3 · last accepted decision 4 · concrete next action 5 · conflicts / missing access fresh session claude -p · codex exec passed ✓ failed ✗ not run —

Read from left to right: the five questions go into a session with no history and come out as one of three verdicts. There's no "sort of passed": either it cites the file, or it doesn't.

The prompt is short and generic on purpose. It doesn't say where the files are: if the agent needs you to point the way, the reading order in AGENTS.md isn't working. This is the exact text, taken from the prompt library and stored in the kit at prompts/03-readback-handoff.md:

Goal: paste into a fresh session of any runtime, inside the project folder.

Read this project's active instructions, current context, task, and latest handoff. Do not edit.
Report: (1) the current objective and acceptance criteria; (2) one important project rule,
with its exact source file; (3) the latest accepted decision; (4) the next concrete action; (5)
conflicts, stale facts, or missing access. Separate what the files establish from what you
infer. Do not rely on a previous conversation.

How to check: the answer has 5 numbered items and each one names a project file. "Separate what the files establish from what you infer" is the most important part: it forces the agent to admit what it made up.

New here? "Fresh session" means an agent process that starts from scratch, with no memory of the previous conversation. In Claude Code it's claude -p "..."; in Codex it's codex exec "...". Everything the agent knows about the project has to come from the files it reads at that moment.

Key concepts

Readback

Continuity test: a fresh session answers 5 questions citing files.

Established vs inferred

What the files say, kept apart from what the agent deduced.

No pointing the way

The prompt doesn't say where the files are; the reading order has to work on its own.

Do not edit

Readback only reads. An agent that "fixes" things during the test contaminates the evidence.

2

🧪 readback-test.sh: claude -p and codex exec

Pasting the prompt by hand works, but it gets tiring and leaves no trail. The kit has a script that runs both executions in sequence, inside the project folder, and saves each runtime's raw answer in relatorios/. The verdict is still yours: the script marks "not run" only when the runtime doesn't exist on the machine.

Goal: run the readback on both runtimes against one of your projects and keep the evidence.

cd ~/projetos/agente-claude-codex
scripts/readback-test.sh ~/projetos/<seu-projeto> both
# → claude (fresh session in /home/.../<seu-projeto>)
#   saved: relatorios/readback-claude-2026-09-14.md (25 lines)
# → codex exec (fresh session in /home/.../<seu-projeto>)
#   saved: relatorios/readback-codex-2026-09-14.md (386 lines)

How to check: both files exist in relatorios/ and have more than a dozen lines. If one of them only holds a harness warning, that runtime counts as not run, even if the file exists. Replace <seu-projeto> with the real folder; both can become claude or codex to run just one.

Under the hood, the script is simple: it extracts the prompt from the prompts file, enters the project folder, calls claude -p and then codex exec --skip-git-repo-check, and redirects the output. The part that matters is what it does not do: it doesn't force a sandbox on Codex. The first version forced -s read-only and the test failed before reading a single file. You'll see that case in topic 5.

✓ The script does

  • Runs each runtime in a fresh session, inside the project folder.
  • Saves the raw answer with the date in the name, so it becomes versioned evidence.
  • Marks "not run" when the binary doesn't exist, instead of failing.
  • Prints the pass criteria at the end, so you can read them next to the answer.

✗ The script doesn't

  • Give the verdict. A file with 386 lines can be a failure.
  • Edit anything in the project, not even when the agent suggests fixes.
  • Force a sandbox: it respects the sandbox_mode in ~/.codex/config.toml.
  • Run in a loop. Each codex exec uses up OpenAI account quota.

💡 Practical tip

Run the readback right after finishing the core (module 2.3) and again after porting the skill (module 2.4). The first measures the context; the second measures whether the installed skill changed anything in the answer. If the answer is identical, the runtime isn't discovering the skill.

Key concepts

claude -p

Claude Code's non-interactive mode: takes the prompt, answers, exits.

codex exec

The Codex CLI equivalent; --skip-git-repo-check avoids refusal outside a repo.

relatorios/

Dated, versioned evidence; without it the test "didn't happen".

Quota

Every run costs; run it per project, not out of curiosity.

3

🔎 Reading the answer: does it cite the right files?

The answer arrives as a long block of text. Don't read it as prose: read it as a checklist. For each of the five questions, you look for three things: the item exists, it names a project file, and its content matches what's in the file. The fourth question has one extra criterion: the next action it cites has to be the same one that's in tasks/current.md.

file exists ls shows AGENTS.md ≠ proof agent read it shows up in the tool log ≠ proof agent used it answer cites and matches the file = proof ✓

Three steps that many people mix up: the file existing and the agent having read it are necessary, but only the third, the answer using the content and matching it, counts as evidence.

1

Goal and definition of done

It has to come from tasks/current.md. If the agent describes the goal from the README, the current task is not being read.

2

Rule with source file

It must name AGENTS.md (or the CLAUDE.md that imports it). A rule without a source is a guess.

3

Last accepted decision

Comes from context/decisions/. A good answer distinguishes "proposed" from "accepted", as both runtimes did in the real case.

4

Next action

It must match tasks/current.md and handoffs/latest.md. If the two diverge, the agent should say so in question 5.

5

Conflicts and missing access

The most valuable part. An agent that finds real inconsistencies is actually reading. One that says "no conflicts" in a freshly created project probably didn't read.

📋 Pass criterion, in one line

All five answers cite AGENTS.md, tasks/current.md and handoffs/latest.md, and the next action in the answer is the same as in the task. Anything less is a fail, even if the prose is nice.

Key concepts

File citation

The minimum unit of evidence: file name + matching content.

Evidence ladder

Exists → read → used. Only the last rung is proof.

Next action matches

Answer = tasks/current.md = handoffs/latest.md.

Conflict found = good sign

Whoever finds a real inconsistency is reading.

4

🧾 The real case: Codex found three holes in its own kit

On September 13, 2026, the readback was run against the kit's own repository, minutes after it was created. The result is the best argument for the test: both runtimes passed, and each one pointed out real problems that whoever wrote the repo had not seen. Below are verbatim excerpts from the files saved in relatorios/.

Real excerpt: relatorios/readback-codex-2026-09-13.md, question 5.

5. Problems found:
   - Failed: reading handoffs/latest.md; file missing. Only the
     template exists at template/handoffs/latest.md.
   - Documentation conflict: PLANO.md says no readback was run;
     context/current-state.md says the first run took place.
   - Ambiguity: the skill groups in the plan add up to 94, although the
     declared gap is 89; the overlap is not explained.
   - Not run: runtime validation, drift and the isolated-copy test.

No files were edited by me.

What this proves: Codex read PLANO.md, context/current-state.md and the skills matrix, cross-checked all three and found a wrong sum (73+17+4 = 94, not 89), a handoff that only existed as a template, and a contradictory sentence. All three were fixed in that session.

Real excerpt: relatorios/readback-claude-2026-09-13.md, question 5 (the answer came in English; the content is what matters).

5. Conflicts, stale facts, missing access.
   - The working tree has six modified files and an untracked handoffs folder,
     all uncommitted. The handoff's "estado aceito" says "repo criado, commit
     inicial", which does not reflect these later edits.
   - There is no git remote configured, so the open question about publishing
     to inematds/agente-claude-codex is unresolved and a push is currently
     impossible. The local git email is already the correct inematds address.
   - Branch is master, while the environment lists main as the main branch.

What this proves: Claude went beyond the Markdown files and looked at the git state. The uncommitted edits and the master branch were fixed in the next commit; the remote was created when the owner authorized publishing.

1

1st round on Codex: failed before reading

The script forced -s read-only; the bwrap sandbox doesn't start on this host because of AppArmor. The whole answer said "I couldn't read the files".

2

Minimal fix and 2nd round: passed

The flag was removed; the script now respects the config's sandbox_mode. Codex cited AGENTS.md, PLANO.md and tasks/current.md and pointed out the three holes.

3

Claude: passed and found git debt

It cited AGENTS.md, context/decisions, tasks/current.md and handoffs/latest.md, and listed what was out of place in the repository.

4

Handoff updated with the evidence

Each check went into handoffs/latest.md as passed, failed or not run, with the round number. The next agent reads that, not the conversation.

Notice: both runtimes agreed on questions 1 to 4 and differed only in what each one chose to investigate further. That is exactly what you expect from a good portable core: the context is the same, the executor changes.

Key concepts

Verbatim evidence

An excerpt from the saved answer, not a summary from memory.

Real hole

Wrong sum, missing file, contradictory sentence: things the author didn't see.

Round

Each run has a number; "passed on the 2nd round" carries the history.

Same context, different executor

Agreement on the first 4 questions is the signal of portability.

5

🧯 FALHAS.md: one line per failure

Every failure the readback exposes becomes a line in a file at the project root: date, what broke, the smallest possible fix, and whether the cause was prompt (you asked in a way that induced the error) or infra (machine, network, service, permission). After about ten lines the pattern shows up on its own, and you stop rebuilding things that only needed a safeguard.

Real file: FALHAS.md from the kit, the two lines that came out of this readback session.

# Failures (most recent on top)

| date | what broke | smallest fix | prompt \| infra |
|---|---|---|---|
| 2026-09-13 | readback-test.sh forced `-s read-only` on codex exec; bwrap fails due to AppArmor on this host | remove the flag, respect sandbox_mode from config.toml | prompt \| infra |
| 2026-09-13 | audit.sh summary counted lines from section 3 (73+17+4=94 ≠ 89) | restrict grep to section 2.1 | prompt |

How to use: copy the header into your project. Write the line when you finish fixing, before moving on to the next task. If the fix was "rewrite everything", it was probably just a missing guard, retry or validation; record that.

✓ Good line

  • One line, no narrative. Long details go in a separate, linked file.
  • Fix named as a minimal action: "remove the flag", "restrict grep".
  • Marks both causes when it is both, as in the sandbox case.
  • Most recent on top, so you can glance and see the pattern.

✗ Bad line

  • "Codex threw an error, I redid the script." No what, no minimal fix.
  • Written at the end of the session, from memory, three failures at once.
  • No prompt or infra classification: loses the most instructive information.
  • Kept only in the conversation, which the next agent can't see.

New here? A "sandbox" is a playpen Codex creates with a tool called bwrap so the agent doesn't touch anything outside the folder. "AppArmor" is a Linux security module that, on this machine, forbids the technique bwrap uses. Result: the playpen doesn't come up and the agent can't read anything. The fix wasn't "repair Linux"; it was to stop forcing the playpen on a host where it doesn't work.

Key concepts

Smallest possible fix

A cap, a retry, a guard, a validation. Rarely a rewrite.

Prompt vs infra

You induced the error, or the machine/service failed. Sometimes both.

When to write

When you finish fixing, before the next task. Never at the end of the session.

Pattern emerges

After ~10 lines, you see what always breaks and protect it ahead of time.

6

🚦 When to mark passed, failed or not run

The three states are the grammar of every report in this course, and the third is the most important. Not run is not shameful: it is honesty. The serious mistake is the opposite: marking "passed" on a check nobody executed because the file "looked right". The prompt library is explicit: a readable file, a successful import or valid syntax are not proof of equivalent behavior.

✓ Passed

The check was executed, the result was observed and it meets the criterion. There is an evidence file or command output to show.

✗ Failed

Executed, observed, doesn't meet it. It gets recorded with the reason and becomes a line in FALHAS.md. A preserved failure is worth more than an invented pass.

— Not run

Not executed, for lack of runtime, time, an owner decision or quota. Write down the exact step to reproduce it later.

Real example: the "Checks run and result" block from the kit's handoffs/latest.md, after the readback.

## Checks run and result
- scripts/audit.sh — passed (89 skills only in Claude: 71 reusable, 15 adapter, 2 native, 1 without SKILL.md).
- scripts/adapt-instructions.sh ~/.claude --dry-run — passed (71 portable lines, 7 Claude residue).
- template/scripts/check.sh — passed.
- scripts/readback-test.sh . codex — passed on the 2nd run (1st failed due to bwrap sandbox; fixed).
- scripts/readback-test.sh . claude — passed: cited AGENTS.md, context/decisions, tasks/current.md and handoffs/latest.md.
- scripts/sync-skills.sh — not run (awaiting pilot choice).
- Isolated copy + check.sh — not run.

Notice: both "not run" entries are there, with the reason. Whoever opens the next session knows exactly what is left, and doesn't find out at the worst moment that "sync-skills" was never tested.

⚠️ The mistake to avoid

Declaring "migration complete" while a required flow is "not run". The prompt library says the opposite: recommend the smallest remaining step, never a speculative rewrite of the whole system.

Key concepts

Three states

Passed, failed, not run. There is no fourth state.

Attached evidence

A "passed" with no file or command output is a "not run" in disguise.

Reproduction

Every "not run" comes with the exact command to run it later.

Smallest remaining step

The report ends with an action, not with a rewrite plan.

Self-check (optional): the readback in Codex returned 380 well-written lines, but none of them cites tasks/current.md. How do you mark it?

🎯 Module summary

Five questions, fresh session — goal, rule with source, decision, next action, conflicts; without pointing to where the files are.
readback-test.sh — runs claude -p and codex exec, saves to relatorios/, and doesn't give the verdict for you.
Evidence ladder — exist, read, use. Only an answer that cites the file and matches it is proof.
Real case and FALHAS.md — both runtimes found real gaps; each failure became one line with the smallest fix.
Passed / failed / not run — the three states, always with evidence or with the step to reproduce.

Next module:

2.6 — Handoff and prime: the daily cycle