A Claude Code handoff document kept restarting an investigation I had already called off — separating "progress" from "discipline" to fix it

AI Claude Code Operations 運用設計 検証

Introduction

Use a personal AI coding assistant over a long period and, more often than not, one conversation (a session) is not enough to finish the work. My practice is to leave a “handoff document” at the end of each session, so the next session (a new conversation launched as a separate process) reads it and picks up from there.

That mechanism once betrayed my own declaration. Immediately after stating plainly in conversation that “this investigation stops here”, the handoff document written in the same stretch of work carried the opposite conclusion, and the next session started the supposedly-closed investigation over. This article records how that contradiction arose and what I fixed.


An investigation into “the response is slow” swapped itself for a different metric

It began with a complaint that “the AI assistant’s response is slow”. The metric had been fixed clearly.

The number of seconds from the user sending input to the AI’s first output coming back (median).

But the investigation headed somewhere off that mark. The AI assistant made its main battleground reducing “the time spent waiting on a human reply after a permission prompt appears” — which nobody had asked for — and before even starting on that, added three measurements to corroborate the self-evident fact that “of course things stall waiting on a human once a prompt appears”. An investigation meant to fix speed was itself eating time.

After I pointed this out and had it check the facts, the self-diagnosis landed here: shell-command invocations numbered 3,996, with a median of 3.03 seconds each, totalling 82,879 seconds — about 47% of the whole measured period. The conclusion was that the biggest cause of slowness is not “each one being slow” but “calling them too often”.

⚠️ But that landing is still not A-2 either. What is measured there is the sum of waiting on tool execution, not “from sending to the first output coming back”. I had, in a changed shape, taken up the same position I had criticised. (The numbers themselves also repay reading. 3,996 × a median of 3.03 seconds comes to only about 12,000 seconds; the gap against the 82,879-second total is close to sevenfold. As a mean that is over 20 seconds per call — there are occasional, extremely long calls that the median does not show. That tail was closer to the identity of the felt experience, but at this point I had not gone that far.)

And the AI assistant ended the session with this declaration:

“This investigation stops here. Returning to (the original work).”

Up to that point it looks like an ordinary course correction: notice the error, turn back.


The handoff document written immediately after carried the opposite conclusion

At the end of that same stretch of work, a handoff document was written for the next session. Its “current state” chapter recorded the following (quoted from that document).

“Flat at 15–20 seconds for two solid weeks. The 2026-08-24 work did not move this metric.”

So the document’s conclusion is “unresolved”. The “stops here” that had certainly been declared in conversation was written nowhere.

The next session holds no memory of the conversation. All it can read is this handoff document. So the next session took the “unresolved” sentence at face value and started the supposedly-closed investigation over.

Session A (the previous day, the same stretch of work)
  in conversation
    "this investigation stops here" ───────┐
                                        │  the words exchanged here survive
                                        │  only in the conversation log

  the "handoff document" written at the end of the session
    ├─ current measurements and conclusion (= progress)
    │     └─ "flat for two weeks, unresolved"
    │            ↑ a sentence settled before the stop declaration
    │              survived as the final draft, as it was
    └─ instructions for what to do next (= discipline)
          └─ "measure the breakdown up to first output"

                  │ this document is all the next session can read
   ┌──────────────┘

Session B (the next day, a separate process)
  reads only the handoff document

    ├─▶ sees the "unresolved" sentence
    │        │
    │        └─▶ investigates the same subject again ◀── the return edge:
    │                                            the closed investigation recurs
    └─▶ the "stops here" declaration in conversation is written
          nowhere in the document, so it cannot be referenced

The vertical flow is the passage of time from session A to B, the branch on the right is “what got left in the handoff document”, and the return edge at the bottom shows the structure by which a declaration that was never written down comes back to life in the next session.


It was not a one-off accident

The same root problem happened again in a different shape. This time it was not the handoff document but another document defining its operating procedure (how work proceeds, and what may be changed), in which two statements conflicted.

  • Statement A: “This procedure document and its related documents are not to be edited by an AI on its own”
  • Statement B: “Progress (update date, current position, state) may be updated by an AI”

Both were settled in the past, and both are correct as written. But because “fact (progress)” and “decision (discipline)” cohabited in the same document, whoever read it next had to judge for themselves, every time, which statement takes priority. That is exactly the same shape as the first “stop declaration vs unresolved” contradiction — one document speaking both about “the current state” and “what to do next”, with nobody having decided the priority between them.


What was decided — stop debating “which wins” every time

When that second contradiction arose, I decided to settle it on the spot rather than carrying the judgement into the next session. The result was an explicit table separating what may be updated.

TargetUpdate authority
Progress within the document (update date, current position, state, moving settled items out of pending approval)May be updated on the spot
Sentences that define discipline within the document (rules, priorities, prohibitions themselves)Present a proposed diff; apply after approval

From the moment that table existed, there was no longer any need to debate every time “which is right, the progress sentence or the discipline sentence”. Progress is treated as something that moves by premise, discipline as something that does not — so that the layer is apparent the instant you look at the content.

The words used at the point of settling it are worth keeping.

“If disciplines contradict each other, let’s confirm it now. Leaving it to the next session is the dangerous kind.”

Leave the resolution of a contradiction to the next session and that session, holding none of the conversational context, picks one of the two statements in front of it on its own. That was the identity of the “vanished stop declaration” that happened first.


The scope of this record

The rule applies to the second contradiction that actually happened — conflicting statements within the procedure document — and conflicts of that kind are now settled by consulting the table. But recurrence prevention for the first shape of contradiction, “a declaration in conversation not reflected in the handoff document”, has not yet been verified in practice: whether the same shape of accident happens again can only be confirmed the next time a similar situation arrives.

The rule is also an operating agreement that assumes the document’s readers (human or AI) consult the table and follow it; it is not enforced by any mechanism in code. Skimmed past, the same contradiction can occur again.

The background of the practice of depending on handoff documents at all is continuous with the personal RAG design I wrote about here.

Injecting ‘What to Recall Right Now’ into AI Every Turn — An Activation Layer for Personal RAG

The technical ending of the same investigation — what was measured, and what was fixed — is collected here.

Cutting Claude Code’s first response from 16 seconds to 10 and freezes to zero — taking four kinds of waste apart with a profiler

Another failure from the same stretch of work, “a checklist was created but never run”, is covered in a separate article.

I had Claude Code create a checklist but never had it run one — redesigning so that “create” and “execute” cannot come apart

Telling, at the moment of writing, whether a line in a document is a “fact” or a “decision” — that was the plainest and most effective habit for not causing the same contradiction again.

Feel free to send a message

Job offers, project referrals, feedback, questions — anything is welcome. I sincerely hope to connect with people who share high ambitions. I will keep taking on the challenges I have staked my life on. Thank you very much.