Topic 02

Pointing, Not Pasting

Context

The agent can read files, run commands and search the repository, so the most precise thing you can give it is a pointer: the file, the function, the failing test, the exact error. A paraphrase passes through your understanding before it reaches the agent, and it loses whatever you did not notice on the way.

The rule that follows is short. Point at the source and let the agent read it. Paste only what it cannot reach on its own, and trim what you paste to the part that matters.

What a Pointer Is

A pointer is anything that lets the agent fetch the real thing itself: a path, a function name, a test name, a command that reproduces the problem, a commit. Each one leads to the current, complete source instead of your summary of it. "The deadline logic in refunds" is a pointer. "The bit that works out when people can cancel" is a description that the agent has to turn back into a search, starting from your words.

Pointers also age well inside a session. The file the agent reads is the file as it is now, after your last edit and the agent's last change. A summary you wrote ten minutes ago describes code that may have moved since.

At Cragmoor the useful pointers are concrete: a module name such as refunds, a test name from the refunds tests, a booking number from the support ticket, the commit where a behaviour last worked, the command that replays a member's cancellation. Each one fits on a line, and each one lets the agent fetch the real thing, read around it and follow it where it leads, which a paragraph of your own description never lets it do.

What Paraphrase Loses

Support forwards a complaint: a member cannot cancel a booking. You have looked at it for two minutes and you have a theory, so you write "cancelling crashes for some members, I think it's the new three-class packs". The agent takes that sentence at its word. It searches for cancellation and for packs, opens the pack pricing, and starts reasoning about rounding.

The stack trace from the failed cancellation says something else. It names refunds, the deadline function and the line, and its last frame is in schedule, where the class's start time arrived empty. Booking 48213 is for a class that has no entry in the schedule, so it has no start time to count back from. The trace already holds the address of the cause. Your sentence held a guess about packs, and the agent followed the guess.

Cancelling booking 48213: the traceback
Traceback (most recent call last):
  File "src/cragmoor/booking.py", line 30, in cancel
    return refunds.refund_cents(booking, at)
           ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
  File "src/cragmoor/refunds.py", line 32, in refund_cents
    deadline = refund_deadline(booking.starts_at, booking.gym)
  File "src/cragmoor/refunds.py", line 21, in refund_deadline
    start = schedule.localize(starts_at, gym.time_zone)
  File "src/cragmoor/schedule.py", line 13, in localize
    return wall_clock.replace(tzinfo=ZoneInfo(time_zone))
           ^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'replace'
Cancelling booking 48213: the stack trace
RangeError: not a wall-clock time: null
    at Module.localize (src/schedule.ts:11:42)
    at refundDeadline (src/refunds.ts:14:26)
    at Module.refundCents (src/refunds.ts:25:20)
    at cancel (src/booking.ts:27:18)
Cancelling booking 48213: the stack trace
java.lang.NullPointerException: Cannot invoke "java.time.LocalDateTime.atZone(java.time.ZoneId)" because "wallClock" is null
	at org.cragmoor.Schedule.localize(Schedule.java:20)
	at org.cragmoor.Refunds.refundDeadline(Refunds.java:17)
	at org.cragmoor.Refunds.refundCents(Refunds.java:28)
	at org.cragmoor.Booking.cancel(Booking.java:24)
One bug report, written two ways
The paraphrase"cancelling crashes for some members, I think it's the new packs"
What the agent does first: searches for "cancel" and "pack", opens the pricing code and starts on rounding.
What it inherits: your hypothesis, which is wrong.
The pointersbooking 48213, the trace, the command that replays it
What the agent does first: opens the deadline function in refunds at the line the trace names, then the schedule helper below it.
What it inherits: the evidence, and no theory at all.

The difference is not that one report is longer. The pointer version is shorter in your words and carries more information, because the trace and the booking number are raw evidence that your understanding never touched. Chapter 10 builds a debugging method on exactly this, and the same habit makes a good bug report for a person, as QA & Software Testing for Beginners shows in its chapter on bugs.

Why Pasting Code Is Worse Than Pointing

Pasting a function into the chat feels helpful, and it is the weaker choice three times over. The paste is a snapshot: if you copied it before your last edit, the agent now reasons about a version that no longer exists, and it may write its change against lines that are not in the file. It costs context twice, because the agent usually reads the file anyway. And it arrives without its callers, so the agent cannot follow the calls out of it the way it can from the file.

"Read the deadline function in refunds and its tests" gets the current file, costs one read, and leaves the agent free to open whatever that function calls. The same request with forty pasted lines gets a stale copy, then a fresh read, then a diff written partly against the copy.

Run It, Don't Describe It

For a behaviour that is wrong, the best pointer is a command that shows it: the single failing test, the script that replays booking 48213, the request that returns the wrong refund. A command lets the agent run the problem before its change and again after, which turns "I fixed it" into evidence you can check. Chapter 3 set up the commands for exactly this, and Chapter 10 starts every debugging session from a reproduction.

A description of a behaviour gives the agent nothing to run. It will write a plausible fix and report success, and the report will sound the same as it does when the fix is real.

At Cragmoor the reproduction for booking 48213 is one command: a small replay script the support team uses, which loads the booking from a copy of the test data and calls the same cancel function the app calls. It fails with the trace above. Given that command, the agent can run it, read the trace, change the code and run it again, and you can do the same before you read the diff. Without it, the agent would have to construct a booking with no start time on its own, from your description of one, and you would have to trust that it built the right one.

What It Cannot Reach

Some evidence lives where the agent cannot go: the ticket in a tracker it has no access to, a production log, a message from a member, a screenshot. These you paste. Trim each one to what matters, and take out anything secret before it goes in, because whatever you paste is sent to the model provider along with the rest of the context (Chapter 12).

Trimming is where most pasted logs go wrong. Five thousand lines of log around a failure fill the window with noise and push earlier material out of the agent's attention. The twenty lines around the failure and the command that reproduces it do more. The fifth topic in this chapter covers the other option, connecting a source such as the tracker deliberately, and what that lets in.

Personal data needs the same care as secrets. The member's message from support names the member, the class and sometimes a phone number; none of that helps the agent find a bug in a deadline. Paste the part that describes the behaviour, replace the member's details with the booking number, and leave the rest in the ticket, where the people who need it can read it. Chapter 13 turns this into a team rule about what may be sent to a provider at all.

Misconceptions
  • "Explaining the problem in my own words helps it understand." Your words carry your hypothesis. When the hypothesis is wrong, as "it's the new packs" was, the agent inherits it, while the raw error carries no hypothesis at all.
  • "Pasting the code saves it the trouble of looking." It saves one read and costs a stale or partial copy. The agent can then edit the file on the strength of a version that is no longer there.
  • "The whole log is the most helpful thing to paste." Five thousand lines of log fill the context with noise. The twenty lines around the failure, with the command that reproduces it, give the agent more to work with.
  • "It's polite to describe the codebase first." Prose about the code competes with the code for the agent's attention, and it is your summary rather than the source. Pointers get the agent to the real thing sooner.
  • "If it can search, it doesn't need pointers." A search starts from words. A pointer starts from the answer, which is why the refund task found its second file only when the file was named.
Why It Matters
  • Give paths, names and the failing test instead of descriptions. The agent then reads the current, complete source.
  • Paste errors and stack traces verbatim, trimmed to the failure. The exact text is evidence; a summary of it is opinion.
  • Give a command that reproduces the problem. The agent can then show that its change fixed it, and you can run the same command to check.
  • Paste only what the agent cannot read, with secrets removed. Everything pasted leaves the machine.

Knowledge Check

A member cannot cancel booking 48213, and you suspect the new three-class packs. What should your message to the agent contain?

  • Your theory about packs, explained in enough detail for it to start on the pricing code
  • The booking number, the stack trace verbatim and the command that replays the cancellation
  • A careful summary of what the stack trace says, so the agent does not have to read all of it
  • A paste of the pricing and refunds modules, so the agent has all the relevant code at once

Earlier in a session you pasted a function into the chat. You then edited the file and asked the agent for a change. What is the risk?

  • The agent writes its change against your pasted copy, which no longer matches the file
  • The agent refuses to edit a file that differs from code you have pasted into the session
  • The pasted function is removed from the context as soon as the file on disk is changed
  • The agent merges your paste and the file automatically, keeping the newer of the two lines

A failure produced 5,000 lines of log. What should go into the session?

  • All 5,000 lines, because the cause may be anywhere and the agent reads quickly
  • A one-line summary of the failure written in your own words, to save context space
  • The twenty or so lines around the failure, plus a command that reproduces it
  • Nothing from the log at all, because the agent can find the log file on its own

When is pasting the right way to get material into the session?

  • When the material is code in the repository that you have already read yourself
  • Whenever the material is short enough that pasting it costs almost nothing
  • When the agent cannot reach it, such as a member's message or a production log
  • When you want the agent to give that material more weight than other context

Why is a reproducing command a stronger pointer than a description of the wrong behaviour?

  • Commands are given a higher priority by the model than any text in the window
  • The agent can run it before and after its change, so a fix becomes something checkable
  • A command is shorter than a description, so it saves context for the rest of the task
  • Descriptions are discarded when the window fills, but commands are kept by the tool

You got correct