The warehouse scanner rejected 327 rows from shipments_aug18.csv at 8:12 a.m. Every bad cell looks like 08/18/26. The contract on the dock is 2026-08-18. You open Grok Build and type “make the export work.” Fourteen files change. The Dockerfile picks up a new base image. A logger grows extra fields. format_ship_date still prints a two-digit year with slashes. The next scan rejects 327 rows again.
This is Part 17 of the Grok series. Part 16 got the grok binary onto a sandbox machine. Now we use it without letting the agent redecorate the repo. The loop is explore, change, check. If you still mix chat tabs with a folder agent, keep the four Grok surfaces nearby.
UI labels move. Re-check the Grok Build overview the week you teach this to a teammate. Headless grok -p can run the same words. It will not make a sloppy prompt safer.
A four-beat project loop you can run
- A four-beat project loop you can run in one sitting: ask, explore, small diff, check
- How
@file mentions keep the agent in the room you meant - Prompt shapes that change one function instead of fourteen files
- What “check” means: run something, open the diff, keep or restore with git
- A worked toy for
ship_datewith before and after Python and a three-row result table
The loop on one card
Grok Build is useful when you already have a folder and a specific mess. It is a poor “do my job” button. The 327-row reject is a specific mess. “Make the export work” is not a loop. It is a wish.
Use four beats, in order:
- Ask with a boundary. Name the symptom, the file you suspect, and what the agent must not touch.
- Explore before any edit. Have it list call sites, print the current function, and quote the scanner contract. No writes.
- Change one thing. One function, one format string, one test. Plan mode if the agent wants a tour.
- Check. Run the toy. Open the diff. Restore anything extra. Then stop or start a new loop.

Skip explore and you get the 14-file patch. The model is trying to be helpful. Helpful, unscoped agents rewrite logging “while they are here.” Your review budget at 8:12 a.m. is not 14 files. It is one function and a three-row printout.
Git still sits under the loop. Commit or stash before you start if the branch already has other work. If the agent goes wide, git restore on the extra paths is faster than arguing in the TUI. Rollback is git. The next part in this series spends more time on that. Tonight, treat a clean status as part of “check.”
Explore with @ files
The TUI lets you point at a path with @. Official first-run examples look like @src/main.rs Walk me through this file. Same idea in a Python export folder: name the file, then ask a question that does not require a write.
Good explore prompts are nosy and small.
@exports/csv_writer.py Find every function that writes ship_date.
Quote the current format string.
List other files that call format_ship_date.
Do not edit anything.That prompt does four jobs. It pins the file. It names the function. It asks for callers so you learn whether the bug is local. It forbids edits. If the answer says “callers are only write_shipments_csv in this same file,” you have a one-file change. If the answer says eight packages import it, you still change one function, but you plan a wider check.
Bad explore prompts hand the agent a mood.
This export is a mess. Clean it up so warehouse stops yelling.
Also tidy anything that looks old.“Tidy anything that looks old” is how Dockerfiles move. The scanner does not care about your base image. The scanner cares about YYYY-MM-DD.

If the repo is larger than one file, keep explore in plan mode. /plan plus “no file edits until I approve” stops the agent from “fixing” while it reads. Shift+Tab cycles modes in the TUI. Use ask/watch permissions on a morning when 327 rows are already wrong. Auto-approve is for a later day, on a folder you trust, after this loop is muscle memory.
Read the explore answer out loud. If you cannot point at a single function after that answer, you are not ready to change code. Ask again. Attach another @ file. Do not reward a vague map with “ok, implement.”
Change one thing
Once explore names format_ship_date, the change prompt should be almost boring.
@exports/csv_writer.py Change format_ship_date so it returns YYYY-MM-DD.
Do not change logging, Docker, or other modules.
Do not add dependencies.
Show the diff for this file only.Notice what is missing. There is no “improve readability.” There is no “while you are in there.” There is no “use best practices.” Those phrases are permission slips for extra files.
If the agent proposes a helper module, a new date library, and a config flag, say no. The scanner contract is a format string. A format string does not need a platform. You can add tests after the function is right. You can restyle the file in a second loop if you still care at lunch.
One change also means one commit later. Mixed commits (date fix + logger + Docker) are how the 14-file disaster lands in main because someone reviewed the date line and missed the base image.
Check: run, test, open the diff
A green-looking TUI message is not a check. Check is something you can see without trusting the model’s summary.
- Run the function on three known dates and print the strings
- If the repo has tests, run the narrow file, not the whole suite first
- Open
git diffyourself. Count files. If the count is not 1, stop - Restore extra paths. Keep the one hunk you asked for
A check prompt you can paste after the edit:
Run a three-row toy for format_ship_date using
2026-08-18, 2026-08-19, and 2026-01-05.
Print input, output.
Do not write more files.
Then stop.Then leave the TUI (or open a second terminal) and run git yourself:
git status
git diff --stat
git diff exports/csv_writer.pyIf git diff --stat lists 14 paths, the loop failed even if the date string is now correct. Restore the extras. The date fix can stay. The Dockerfile does not get a free ride because the model was “already in the repo.”
Headless note: grok -p "make the export work" is the same wish, with fewer chances to say no. Do not move this loop to CI until the prompt names a file, forbids extra writes, and you have a test that fails on 08/18/26.
Worked toy: format ship_date
Here is the whole bug in one function. Warehouse DB already stores ISO dates. The writer converts them to a US short date because someone once opened the CSV in Excel and wanted slashes. The scanner at the dock is not Excel.
Before:
from datetime import datetime
def format_ship_date(value):
"""value arrives as YYYY-MM-DD from the warehouse DB."""
parsed = datetime.strptime(value, "%Y-%m-%d")
return parsed.strftime("%m/%d/%y")
samples = ["2026-08-18", "2026-08-19", "2026-01-05"]
for raw in samples:
print(raw, "->", format_ship_date(raw))What that prints (the 327-row morning):
| input | before | scanner |
|---|---|---|
| 2026-08-18 | 08/18/26 | reject |
| 2026-08-19 | 08/19/26 | reject |
| 2026-01-05 | 01/05/26 | reject |
After. Same function, one format string. No new package. No extra files.
from datetime import datetime
def format_ship_date(value):
"""Scanner contract: YYYY-MM-DD only."""
parsed = datetime.strptime(value, "%Y-%m-%d")
return parsed.strftime("%Y-%m-%d")
samples = ["2026-08-18", "2026-08-19", "2026-01-05"]
for raw in samples:
print(raw, "->", format_ship_date(raw))What that code prints after the one-line change:
| input | after | scanner |
|---|---|---|
| 2026-08-18 | 2026-08-18 | accept |
| 2026-08-19 | 2026-08-19 | accept |
| 2026-01-05 | 2026-01-05 | accept |
Yes, the “after” function parses ISO and writes ISO. That looks silly until you remember the before version existed to please a human in Excel. If you still need a slash column for a person, add a second field later in a second loop. Do not smash both needs into one column and then ask the agent to “make everyone happy.”
A full first session on this toy, in order:
- Copy the before function into
~/sandbox/warehouse-export-toy/exports/csv_writer.py. cdthere.git addand commit so you have a restore point.- Start
grok. Stay on ask/watch. Use plan mode if the agent gets chatty. - Paste the explore prompt with
@exports/csv_writer.py. - Paste the one-function change prompt.
- Run the three-row script. Compare to the after table.
git diff --stat. One file. If not,git restorethe extras.
That is the whole skill. The 14-file version feels faster for thirty seconds. Then you spend the morning unscrewing a logger.
Ask with a boundary
| Mistake | What you get | Fix |
|---|---|---|
| Skip explore | 14-file “cleanup” around a one-line bug | Read-only map first, then one change |
| “Tidy anything old” | Dockerfile and logging in the same diff | Name the function. Forbid other paths |
| Trust the TUI summary | Missed extra files | git diff --stat in your own terminal |
| Check only on the happy date | January still serializes wrong | Three rows, including an early month |
| Headless wish on CI | Same mess, no one watching | Keep grok -p off this job until the test exists |
Ask with a boundary (check)
Rebuild the toy folder from Part 16. Drop in the before function. Run the loop once without letting the agent leave csv_writer.py. If you already have a real export bug, do explore only on that repo today. Change tomorrow, after you can name the function in Slack without opening the file.
The next part in this series is Grok Build tools, skills, and agent workflows. That is where AGENTS.md, skills, plugins, MCP, and subagents start to matter. Learn the loop first. A pile of extra tools on top of “make the export work” is how nine MCP servers join a date-format ticket. Index: Grok series.
Ask with a boundary 3
- Ask with a boundary. Explore with
@files. Change one thing. Check with a run plusgit diff - Forbids are part of the prompt: no logging, no Docker, no extra modules
- A three-row printout beats a confident paragraph in the TUI
- If
git diff --statis not one file, restore the extras before you continue - Save headless
grok -pfor a prompt that already survived this loop in the TUI
Sources
Research and further reading used for this article:
- xAI docs: Grok Build overview (first prompts,
@files, TUI vsgrok -p) - xAI: Grok Build (product home and install entry)
- xAI: Introducing Grok Build (plan mode, diffs after approve, headless note)
- xAI docs: Grok 4.6 (model family behind Build as of writing)
- xAI: Grok FAQ (labels and plan questions to re-check)
- Analytics Made Simple: Learn (related tutorials on this site)
Keep going
Same lessons in your feed
Short diagrams and hooks on Instagram, X, and Facebook.
