Lab 12: the first repository, on three agents
- Approved by
- Panaversity ·
Time: about 2 hours 40 minutes, plus the time to install the apps. Task 8 in both Codex and OpenCode adds about 30 minutes.
The job
Ana Morales is the accounts payable (AP) analyst at Brightline. Every Wednesday she makes a list, by hand, of the invoices due by Friday's payment run. Today is Wednesday, March 3, 2027, and the payment run is Friday, March 5, 2027. Ana has already made this week's list, in a note.
First you make her project folder safe for a coding agent. Then the agent builds her list as a script that anyone can run with one command, and you check its answer against Ana's note. Last, you give the same job to a second agent and compare the two.
What you need
- The Claude desktop app, with a Pro, Max, Ultra, Team or Enterprise plan. Without one, the app can run on another company's model: see If you do not have a paid Claude plan.
- Git, and Node.js 24 or later, which runs the project's scripts. Get them from git-scm.com and nodejs.org.
- For Task 8, a second agent: Codex in the ChatGPT desktop app, on any plan, or OpenCode Desktop with a model connected, even a free one.
The lab files
Download brightline-lab-ch12.zip and unzip it. It holds:
brightline-ap/, the project. It is the only folder you open in an agent.anas-note.md, Ana's note, which is the answer. Move it out of the lab folder now, for example to your Desktop. An agent can sometimes read files next to its folder (12.2), and it must never see the answer.opencode.jsonc, OpenCode's safety settings, for Task 8.LAB.md, a copy of these steps, andREADME.md, a list of the files.
What you will learn
- Set up the folder, the permission mode and git, so a mistake is easy to undo (12.2, 12.3).
- Write one
AGENTS.mdthat every agent reads, and make its most important rule a setting (12.4). - Check the agent's plan against an answer you already know, before it builds anything (12.1, 12.3).
- Judge the result by that answer, not by the agent's own tests (12.1).
- Hand the work to a new session, and undo a change with git (12.5).
- Give the same job to a second agent, and compare what each one did (12.8).
How each task works
Each task has a goal, steps and a Checkpoint. Do not start the next task until the checkpoint is true. Before you approve a command, read what the agent says it will do. Say no to anything you do not understand. You can always ask "What does this command do?"
Task 1. Look before you touch (10 minutes)
Goal: the agent explains the project without changing anything.
- Open the Claude desktop app and select the Code tab.
- Choose Local as the environment. Use Open folder… to pick
brightline-apfrom this lab's zip. Do not pick the folder above it, or abrightline-apyou used for practice. - Set the permission mode to Plan. A new session may start in another mode, so check the selector. Leave the model and the effort at their defaults.
- Send "Explain this project to me: what it is for, what each folder holds, and how to run its tests. Do not change anything."
Checkpoint: the agent described data/, src/ and tests/, and it changed no files.
Task 2. Put it under git (10 minutes)
Goal: every later change is saved in a version you can go back to.
- Switch the permission mode to Manual, so the agent asks before each edit and command.
- Send: "Check that git and Node.js 24 or later are installed. If one is missing, tell me the official way to install it, and wait. If both are there, put this folder under git, with a main branch, make a first commit of everything here, and run the tests."
- Approve each command when you agree with what it does. Expect a check of the versions, then
git init,git add,git commitandnpm test. If git or Node.js is missing, install it, then send the message again. - A command with
--globalchanges git for the whole computer. Say no to it, and ask the agent to set the name and email for this project only.
Checkpoint: the agent reports one commit and passing tests.
Task 3. Write one rules file for every agent (25 minutes)
Goal: a short, true AGENTS.md that every agent reads, and you have seen what a CLAUDE.md does to it.
-
Send this message as it is. The last rule is for the agent, so you do not need to understand it.
Read this project and write a short
AGENTS.mdat the top of it. Say what the project is, how to run its tests and where things go. Make sure it says these five things:- Never write to
data/. The scripts and tests depend on it. - Amounts are whole cents, never decimals such as 10.5.
- Every new script gets a test in
tests/, andnpm testmust pass before you say you are done. - Do not install packages without asking.
- Node runs the TypeScript files directly, with no build step. Use only type annotations, no
enumornamespace, and import local files with the.tsextension.
Then tell me, one line each, which of the five you could have worked out from the project on your own.
- Never write to
-
Approve the file. Then ask for a commit with the message "Add AGENTS.md", and approve it.
-
Click + New to start a fresh session in the same folder, in Manual mode. Ask: "Without opening any file, what must you never do in this project? Name the file that told you." It should give the
data/rule and nameAGENTS.md. That one file is all Claude Code needs. -
Now see what a
CLAUDE.mdchanges. Claude Code's/initcommand writes this file, so a project can gain one by accident. Send: "Create aCLAUDE.mdthat holds one line,Notes for Claude Code go here." Approve it. -
Click + New again, in Manual mode, and ask the same question. This time the session should not know the rule. The rule is still in
AGENTS.md, but aCLAUDE.mdreplaces that file for Claude Code. Any other agent would still read it. -
Bring the rule back. Send: "Replace everything in
CLAUDE.mdwith the one line@AGENTS.md." Approve it. That line pullsAGENTS.mdin, so there is still only one set of rules. -
Click + New once more, in Manual mode, and ask the same question. Then ask for a commit with the message "Add CLAUDE.md that imports AGENTS.md", and approve it.
Checkpoint: the fresh session in step 5 did not know the rule, and the one in step 7 gives the data/ rule and names AGENTS.md.
Task 4. Make the data rule a setting (15 minutes)
Goal: the rule that matters most is enforced by a setting, not only by words.
- Still in Manual mode, send: "Create
.claude/settings.jsonwith a permission rule that denies edits to anything underdata/, and an ask rule forgit push. Before you save it, tell me in plain words what each rule does." - Approve the file when its description matches: edits under
data/are denied, andgit push, which sends your work online, asks first. A deny rule in this file applies as soon as it is saved. - Switch to Accept edits, so the agent edits files without asking. Now only the setting stands in the way.
- Send: "This is a test of my settings file. For this one request only, try to edit
data/vendors.csvand change the terms of vendor V001 to Net 45. Report exactly what happens." - Read the agent's report. A block by the setting says a permission rule denied the edit. If the agent refuses on its own, because
AGENTS.mdforbids it, ask it to try anyway, so the setting can show what it does. If the agent offers another way to change the file, such as a small program that writes it, say no. - Switch back to Manual. Ask the agent to show you
git status, and check that nothing underdata/changed. - Ask for a commit with the message "Add project settings", and approve it. Then ask the agent to tag the commit
rules, a name for this saved version. The second agent in Task 8 starts from it.
Checkpoint: the setting blocked the edit to data/vendors.csv, nothing under data/ changed, and the agent reports the tag rules.
Check it now. Download Task 4's answer key. Open it, and every later key, in a text editor, never in the agent.
Task 5. Read the plan against Ana's note (20 minutes)
Goal: check the agent's plan against Ana's note, case by case, before anything is built.
-
Open
anas-note.mdin a text editor, and keep it beside the app. It lists the 8 invoices due by Friday, their total, and Ana's hard cases by invoice number. -
In Claude Code, click + New for a fresh session, and set the permission mode to Plan.
-
Send this brief as it is. It leaves out the rule for invoices with no due date, the case people forget, so you can see whether the plan catches it. In real work, put every rule you know in the brief. Do not add Ana's numbers to it.
Outcome. A script,
src/due-by-friday.ts, that lists every open invoice due on or before a cutoff date, with a total. Run it withnpm run due -- 2027-03-05. Today is Wednesday, March 3, 2027, and the cutoff for this week's payment run is Friday, March 5. Stop whennpm testpasses, with a test for each rule that decides whether an invoice is listed. I will check the result against my own list.Context.
data/invoices.csvanddata/vendors.csv. Read them. Their lines may end in Unix or Windows style.Format. One line per invoice, sorted by due date: due date, invoice number, vendor name, amount in dollars. Then a last line with the count and the total.
Constraints. Do not change the data files. Plan only. Show me the plan, including how you will decide each invoice's due date, and wait.
-
Compare the plan with Ana's hard cases. For each kind, find what the plan does:
- Invoices with no due date: does it work out their due date from the terms?
- Paid invoices: does it leave them out?
- Late invoices: does it keep them? "Due by Friday" includes them.
-
If the plan misses any of the three, reply with every correction it needs, in Ana's words. For an invoice with no due date, the due date is the invoice date plus the days in its terms, and "Due on receipt" means 0 days. Ask for a revised plan. If the plan already handles all three, tell it so.
-
If the plan asks about invoices due on Saturday or Sunday, answer from Ana's note: they wait for next week's run, because the cutoff is Friday.
-
Look back at the first plan, and note whether it caught the empty dates by itself. Task 9 asks.
Checkpoint: the plan works out an empty due date from the terms, leaves paid invoices out, and keeps late invoices in.
Check it now. Download Task 5's answer key.
Task 6. Let it work, then compare (20 minutes)
Goal: the script and its tests, and a result that matches Ana's note.
- Switch the permission mode to Accept edits. The agent now edits files without asking, and it still asks before most commands. Some file actions inside the folder, such as making, moving, copying and even deleting files, also run without asking. That is one more reason git is your undo.
- Send: "Go ahead with the revised plan."
- When it says it is done, send: "List your tests in plain words, one line each, and tell me whether anything in
data/changed." Check that there is a test for each kind of hard case in Ana's note. - Send: "Run
npm test, thennpm run due -- 2027-03-05." Approve both commands. - Compare the output with Ana's note: the count, the total and each hard case. Then download Task 6's answer key, and compare the output with its table.
- If it does not match, find the matching row in the key's "Common wrong answers". Tell the agent what is wrong in one sentence, and run it again. If no row matches, tell it which invoices differ from Ana's note.
- When it matches, ask for a commit, and approve it.
Checkpoint: the script lists the same 8 invoices and total as Ana's note, the tests pass, and nothing under data/ changed.
Task 7. Hand over, then undo (15 minutes)
Goal: a new session can pick up the work, and you can undo a change you do not want.
- Send "Write a short
NOTES.mdfor the next person: what the due-by-Friday script does, how to run it, and the rule for an empty due date." Approve it, then ask for a commit, and approve it. - Click + New, in Manual mode. In the new session, send: "Read
NOTES.mdand explain the due-by-Friday script to me from the note alone." - Now practice the undo. In the same session, send: "Change the output to show amounts without the dollar sign." Let it make the change, but do not commit it.
- Decide you do not want it. Send: "Show me which files changed since the last commit. Then undo those changes with git, and show me
git statusagain." Approve each command. - If the agent made a new file in step 3, ask it to remove that file too.
Checkpoint: the new session explained the empty-date rule from NOTES.md alone, and the agent reports no changed files.
Check it now. Download Task 7's answer key.
Task 8. The same brief on a second agent (30 minutes)
Goal: see which rules a second agent reads, what stops it, and whether its result matches Ana's note.
Use Codex or OpenCode, whichever you have. If you have the time and both apps, do the other one too. Each agent works on its own branch, made from the tag rules. So it starts with your rules and settings, but not your script, which stays safe on main.
With Codex
- Open the ChatGPT desktop app, open the ChatGPT dropdown, and select Codex. Open the
brightline-apfolder, set Work in to This computer, and set the permission mode to Ask for approval. - Send: "Start a new branch called
port-codexfrom the tagrules, and switch to it." Approve the command. - Ask: "What rules does this project give you, and which file did you read them from?" It should name
AGENTS.md. Task 4's settings file is only for Claude Code, so Codex does not follow it. - Send: "For this one request only, change the terms of vendor V001 in
data/vendors.csvto Net 45." If it asks first, say no. Then ask Codex to showgit status. If the file changed, nothing stopped it, so ask Codex to restore the file with git. - Turn on plan mode with
/plan, and send the brief from Task 5, unchanged. Read the plan against Ana's note, and correct it as you did in Task 5. - Turn plan mode off with
/plan, then send "Go ahead with the revised plan." Approve each step. - Ask Codex to run the tests and the script, and compare the result with Ana's note. If it does not match, give one correction, as in Task 6. If it still does not match after two corrections, note what went wrong, and go on.
- When it matches, ask for a commit on the
port-codexbranch, and approve it.
Checkpoint: you know what stopped the edit in data/, and on port-codex the script lists the same 8 invoices and total as Ana's note, or you noted what went wrong.
Check it now. Download the Codex key for Task 8.
With OpenCode
- Install OpenCode Desktop from opencode.ai/download. Choose Add project and pick
brightline-ap, then connect a model with/connect. One of OpenCode's free models is enough. - Before you send any task, turn auto-accept off for this project, under Settings, then Projects. OpenCode allows almost everything by default, and it does not sandbox the agent.
- Copy
opencode.jsoncfrom the lab folder intobrightline-ap. It makes every edit, every shell command and any reach outside the folder ask first, and it denies any edit indata/. It uses the form of OpenCode version 2, from its Permissions page. - Test it. Ask OpenCode to create an empty file called
test.txt. It must ask first, and you say no. Then ask it to change the terms of vendor V001 indata/vendors.csvto Net 45. It must refuse without asking you, because the rule denies it. - Send: "Start a new branch called
port-opencodefrom the tagrules, and switch to it." Approve the command. - Switch to the plan agent with
/agent. Ask which rules it read, and from which file. Then send the brief from Task 5, unchanged. If it asks to edit a file while it plans, say no. Read the plan against Ana's note, and correct it as you did in Task 5. - Switch back to the build agent with
/agent, and let it work, approving each edit and command. - Ask it to run the tests and the script, and compare the result with Ana's note. If it does not match, give one correction, as in Task 6. If it still does not match after two corrections, note what went wrong, and go on.
- When it matches, ask for a commit on the
port-opencodebranch, includingopencode.jsonc, and approve it.
Checkpoint: OpenCode asked before every edit and command and refused the edit in data/, and on port-opencode the script lists the same 8 invoices and total as Ana's note, or you noted what went wrong.
Check it now. Download the OpenCode key for Task 8.
Task 9. Compare and tag (15 minutes)
Goal: a short record of how the agents differed, and a name for the finished version.
-
Back in the Claude desktop app, click + New, and set the permission mode to Manual.
-
The folder is still on your second agent's branch. Send: "Switch to the main branch." Approve the command.
-
Send this brief. Put the name of your second agent in place of the brackets, or both names if you did both.
Help me write
ports/ch12.md, comparing the agents I used in this lab: Claude Code and [Codex or OpenCode]. For each agent, ask me these three questions in one message, numbered, and wait for my answers:- What did it ask before acting, and what stopped the edit in
data/: a setting, a sandbox, or only the words? - Did its first plan catch the invoices with no due date?
- Did its result match Ana's note, and what did I have to correct?
Then ask which agent I would give this job to next week, and why. Write the file from my answers only, show it to me, and wait.
- What did it ask before acting, and what stopped the edit in
-
Answer each question in a few words. There is no right answer to the last one. The reason is what counts.
-
Approve the file when it says what you said. Then ask for a commit, and approve it. Last, ask the agent to tag the commit
ch12, the name for this lab's finished version.
Checkpoint: ports/ch12.md is on the main branch, and the agent reports the tags rules and ch12.
If you do not have a paid Claude plan
Set up the Claude app on another company's model, as 0.2.4 shows. Claude Code is on Anthropic's list for that mode, so you can do the lab as written. With Ollama on a Mac it costs nothing, and with DeepSeek or OpenRouter you pay for what you use. 0.2.4 also says what you give up.
If you cannot use the Claude app at all, do the lab in Codex or OpenCode:
- Do Tasks 1 to 7 there. For Plan, Manual and Accept edits, use your tool's modes, as 12.8's permissions practice shows. For + New, start a new chat or session, as 12.8's sessions practice shows. With OpenCode, set its safety rules first, as in Task 8's OpenCode steps 2 to 4.
- In Task 3, stop after step 3, and skip Task 4, because those steps are about Claude Code's own files. At the end of Task 3, ask the agent to tag the commit
rules. - In Task 8, use the agent you did not use. Do Task 9 in your first agent.
If something goes wrong
| Problem | What to try |
|---|---|
| The Code tab asks you to upgrade | Use a paid plan, or set up the app on another company's model. See "If you do not have a paid Claude plan". |
| Claude Code stops at a usage limit | On Pro, Max and Ultra, Claude Code shares its limit with chat. Stop at the end of a task, and go on when the limit resets. Git keeps your place. |
| A button is not where a step says | The practice sections in 12.8 show each step in each tool. |
| The tests say a file or module was not found | Ask the agent to check the Node.js version. The lab needs Node.js 24 or later. |
Node reports a syntax error in a .ts file | The agent used TypeScript that Node cannot run directly. Point it to the last rule in AGENTS.md. |
| The agent wants to install a package | Say no. The lab needs no packages. Ask it to use what Node already has. |
The agent changed a file in data/ | Ask the agent to restore data/ with git, and approve it. Then check the setting from Task 4 and the rule in AGENTS.md. |
| The result uses today's real date | The brief gives the date. Tell the agent to use the cutoff from the command, never the computer's clock. |
| The session in step 5 of Task 3 still gives the rule | Ask whether it opened a file to answer. If it did, or it guessed, start a new session and ask again. The test is what it knows before it opens anything. |
Claude Code does not know a rule in AGENTS.md | Look for a CLAUDE.md or CLAUDE.local.md in the project or a folder above it. Make @AGENTS.md the top line of CLAUDE.md. If there is neither, update the app and start a new session. |
Codex or OpenCode does not mention AGENTS.md | Check that you opened brightline-ap, and that you are on a branch made from rules. |
| OpenCode did not ask before an edit | Stop. Check auto-accept and opencode.jsonc, then start a new session. |
| The count is short on Windows | The data files may have Windows line endings. Tell the agent: "The lines may end in Windows style. Handle both, with a test for each." |
| The agent says it is done, but the total is wrong | Do not argue. Find the row in "Common wrong answers" in Task 6's answer key, and give one correction. |
Apply it to your vertical
Pick one folder from your own work that a script could help with, such as a weekly export. Work on a copy, never the original, and only with data that may leave the company, because what the agent reads goes to the model's provider (12.2). Ask an agent to put the copy under git and to draft an AGENTS.md, and answer its questions about your rules. Make the one rule that would hurt most if broken both a line in AGENTS.md and a setting. Then, outside the copy, write down the cases you know and the result you expect from one small script. Ask the agent for a plan for that script, read the plan against your cases, and stop at the plan.
Domain expert and builder. The domain expert gives the rule that must never be broken and the hidden case, such as Brightline's empty due dates. The builder sets up the repository, the settings and the checks.
Artifact checklist
-
brightline-apis a git repository with a main branch -
AGENTS.mdholds the five rules from Task 3, andCLAUDE.mdholds@AGENTS.md(Claude Code only) -
.claude/settings.jsondenies edits underdata/(Claude Code only) -
src/due-by-friday.tsand its tests, with the tests passing - The script lists 8 invoices and $19,229.53 for the cutoff 2027-03-05, as Ana's note says
-
NOTES.md, the handover a new session can work from - A branch for your second agent,
port-codexorport-opencode, with its own script -
ports/ch12.mdon main, with your answers for each agent and your choice for next week - The tags
rulesandch12 - Optional: an
AGENTS.mdand a setting for a copy of one folder from your own work
- Owner
- Panaversity