The handoff to tomorrow’s version of me

Interrupted personal work became easier to resume when I stopped trusting memory and wrote state, evidence, next action, and completion conditions for a future reader.

I lost an afternoon to a task I had nearly finished the day before.

The task was a small W93H correction. A late deployment event was being placed correctly in reconstructed time and incorrectly in response time. I had found the relevant projection, added a failing fixture, and narrowed the defect to one cursor calculation. Then I stopped for the evening.

The next morning, the editor tabs were still open. The test failure was still visible. My understanding was gone.

I reread the issue, replayed the scenario, reopened three source files, and repeated two experiments whose results I had already learned. The work had not been lost from disk. Its state had been lost from me.

I had thought of handoffs as something between people. This was a handoff between two versions of one person separated by sleep and a context switch. It deserved the same engineering care.

Open tabs preserved location, not reasoning

My usual stopping ritual was to leave the environment untouched. Tabs, terminals, browser windows, and a half-written comment formed a physical memory palace. If I returned quickly, it worked.

The method failed under ordinary disturbances:

  • A browser update reopened tabs without their useful scroll positions.
  • A dependency investigation pushed the relevant terminal output out of view.
  • Another urgent task reused the same working tree.
  • A weekend preserved files and erased mental context.
  • An experiment remained open without saying whether its result supported or rejected the hypothesis.

The screen showed where I had been, not why I had gone there.

Bookmarks into code were similarly weak. A line number could move. A function could be relevant for several reasons. A failing test could be the intended starting state or a new regression. The future reader—me—needed a narrative small enough to reload and precise enough to act on.

I stopped treating workspace arrangement as the primary record. It could remain a convenience, but the durable handoff had to survive a clean restart.

A task title was not a state description

The issue title said “Fix late deployment ordering.” It named the desired outcome and none of the current knowledge.

Useful resumption needed at least four things:

  1. Current state: what is true now, including the failing behavior and work already completed.
  2. Evidence: what observations support the current explanation and which alternatives were ruled out.
  3. Next safe action: the smallest concrete step that advances the work without requiring the whole investigation to be repeated.
  4. Completion condition: what observable result will mean the task is done.

For the W93H defect, the handoff became:

State
  Reconstructed view inserts the late deploy by corrected source time.
  Response view should insert it by ingestedAt but reuses the reconstructed cursor.
  Failing fixture: late-deploy-response-order.
 
Evidence
  Raw events and clock projection are correct.
  Projector output diverges only after toResponseRows().
  Removing clock correction does not change the failure.
 
Next
  Split the cursor constructor so response order cannot receive displayTime.
  Run the two late-evidence fixtures before the full suite.
 
Done when
  Both views preserve their intended order, duplicate delivery remains idempotent,
  and the projection-version snapshot changes only where expected.

Writing it took a few minutes. Reading it the next morning restored the decision boundary without reconstructing the entire day.

“Next” had to be executable

My first handoffs ended with phrases such as “continue debugging projection” or “finish tests.” Those were category labels, not next actions.

A good next action reduced uncertainty and had a visible result. It named a location, operation, or question:

  • Run fixture X with correction disabled and compare event 18's two order keys.
  • Add the missing job outcome to the scenario before changing retry code.
  • Ask whether the decision record should reference current or immutable evidence revision.
  • Replace the derived state effect, then verify the live-region announcement after one filter change.

The action did not need to be correct. It needed to be the most justified next experiment under current evidence. If it failed, the result should refine the handoff.

This made stopping easier. I did not need to reach a satisfying code boundary before leaving. I needed to reach a point where the next transition could be named. Sometimes that meant writing a ten-line failing test and stopping before the implementation.

The future version of me could begin with execution instead of orientation.

Evidence prevented circular investigation

I often repeated experiments because I remembered the conclusion and distrusted the memory. “I think the cache is not involved” was not enough to avoid reopening the cache code.

The handoff linked the exact evidence: a test fixture, trace, query, source event ID, diff, or short captured result. It also recorded the question the evidence answered.

I avoided copying huge terminal logs. A bounded excerpt with the command, environment identity, and result was more useful. If raw output was durable and safe to retain, the note linked it. If it contained secrets or unnecessary personal data, I captured only the claim and reproducible path.

Negative evidence received special care. “Not the cache” became:

With cache reads bypassed, event 18 still receives reconstructed order in response view. This rules out stale cached projection for the fixture; it does not rule out cache behavior in deployed runs.

The scope mattered. A local experiment rarely proved a universal negative. Precise evidence prevented the next session from either repeating the test or trusting it too broadly.

W93H had separated observation from hypothesis during incidents. I borrowed the same distinction for ordinary work.

Decisions needed their rejected alternatives

A future reader can see what code exists. It cannot see why an apparently simpler alternative was rejected.

While designing D4U7, I considered storing only the latest version of each proposal. The repository showed the immutable-revision design I eventually chose. Without a decision note, I could later “simplify” it back to last-write-wins and rediscover the lost-intent problem.

I recorded decisions compactly:

Decision
  Store immutable contribution revisions; project one current revision.
 
Why
  Concurrent long-form edits need a shared base and both intentions preserved.
 
Rejected for now
  Field-level last-write-wins: converges but silently removes prose.
  General real-time text CRDT: exceeds the bounded decision-room scope.
 
Review when
  Simultaneous editing becomes a primary use case rather than an exception.

The review trigger kept the decision from becoming doctrine. An alternative rejected under 2020 scope could become appropriate if the product changed.

This was more useful than a long architecture document that explained the entire system but rarely updated with each consequential turn.

Work in progress needed an explicit safety state

Stopping halfway through a change can leave the repository in a misleading condition. A test may fail intentionally. A migration may be generated but not reviewed. A feature flag may be active only in the local environment. A fixture may contain temporary data.

The handoff named whether the workspace was safe to build, run, switch branches, or share:

  • Safe: incomplete code is isolated and existing behavior remains intact.
  • Expected failure: named tests fail because the implementation is not present.
  • Do not run migration: generated output is exploratory and should be discarded or reviewed first.
  • Local fault active: scenario flag must be removed before ordinary testing.

I did not use these labels as a substitute for version control or clean changes. They described the meaning of the current state.

This became especially important when I worked on several personal projects in the same week. A future session could determine whether it was entering a known experiment or an accidental breakage.

The safest handoff sometimes included reverting a temporary manual change before stopping. Recording an obligation was second best to removing a hazard that no longer needed to exist.

The note lived beside the work

I tried a separate daily journal. It captured thoughtful summaries and made task-specific recovery expensive. I had to search by date, remember which day contained the decision, and translate a chronological diary back into the current repository state.

I moved the active handoff beside the task. For a small change it lived in the issue or a temporary tracked note referenced by the branch. For a long architectural thread, a compact decision record stayed in project documentation. Tests and fixtures remained the executable part of the evidence.

The daily journal still helped reflect across projects. It was not the operational source of truth.

The task note linked stable identifiers rather than absolute local paths where possible. A commit, fixture name, incident scenario, document revision, or code symbol survived machine changes better than “the third terminal tab.”

Sensitive scratch data stayed out of the repository. The handoff summarized it without copying credentials, private content, or raw logs whose retention had no purpose.

Location followed the lifetime and audience of the decision.

Starting work became a read transition

The handoff helped only if I actually consumed it. I added a short start ritual:

  1. Read the current state and completion condition before opening more context.
  2. Verify that the named evidence still exists and the workspace matches the note.
  3. Run the smallest relevant test or status check.
  4. Either perform the named next action or revise it based on new state.

This prevented me from beginning with a broad repository search and reconstructing everything despite having written the note.

If reality had changed—another branch altered the same code, a dependency update invalidated an assumption, or the issue was already fixed—the handoff became an old revision rather than an instruction. I updated it with the divergence.

Reading was therefore not passive. It reconciled the previous mental snapshot with current system state.

That idea is becoming central to D4U7. A returning participant should not receive an old page plus a pile of messages. The product needs a transition from the last acknowledged revision to the current one.

Stopping work became a write transition

Before leaving a task, I answered five short prompts:

  • What changed since the previous handoff?
  • What do I now believe, and with what confidence?
  • What is still unknown or blocked?
  • What is the next bounded action?
  • What will count as completion?

If I could not answer the next-action question, I spent a few minutes narrowing the state rather than writing “continue tomorrow.” The inability to name a next step usually meant the investigation had not separated its hypotheses.

I updated the note after consequential experiments, not after every keystroke. Constant journaling interrupted the work it was meant to preserve. The useful cadence was event-based: a hypothesis changed, an alternative was rejected, a risk appeared, or the next action moved.

At the end, I closed disposable tabs. That tested whether the handoff was sufficient. If closing a tab felt dangerous, its important state probably had not entered a durable place.

The clean workspace became a confidence signal rather than a goal in itself.

A handoff included emotional state only when actionable

Some tasks carried frustration. A note such as “this is awful” did not help the next session, but pretending frustration had no effect was unrealistic. It often meant I had repeated an approach, lost confidence in a boundary, or was about to make a broad rewrite for relief rather than evidence.

I translated the feeling into an actionable constraint:

Three attempts to preserve the bidirectional URL synchronization have created new loops. Do not add another guard flag. Re-evaluate which representation should be authoritative.

Or:

The current test harness makes event order difficult to control. Before changing production logic again, add a deterministic clock and explicit delivery sequence.

The note did not need to perform a mood. It needed to protect the future session from entering the same loop without context.

Sometimes the best next action was to leave the architecture alone and return rested. Naming that was better than disguising fatigue as a technical conclusion.

The method exposed oversized tasks

If a handoff required several pages to describe current state, the work boundary was probably too broad.

I split large tasks by independent claims. “Make D4U7 offline” became:

  • Preserve a local draft across reload.
  • Assign stable operation identity.
  • Reconcile base revision on reconnect.
  • Classify delivery policy by action type.
  • Migrate an older outbox shape safely.
  • Explain attention-required state in the interface.

Each task had its own completion evidence and could hand off cleanly. Their shared architecture lived in a short design record.

The decomposition improved implementation as well as memory. A vague feature had hidden different failure models. Draft persistence was a local durability problem. Delivery was a protocol problem. Reconciliation was a domain decision. Interface recovery was a product problem.

A handoff note acted like an informal test of task cohesion. If the “current state” contained five unrelated stories, I had found five tasks.

Tests were part of the handoff, not the whole handoff

A failing test could preserve the expected behavior beautifully. It could not explain why that behavior mattered, what alternatives had been considered, or which risk remained outside the fixture.

For the late deployment defect, the fixture proved the response and reconstructed views needed different order keys. The handoff explained why discovery time and corrected source time answered different questions. Both were needed.

Likewise, a passing test said the encoded case worked. It did not say whether the work was complete. The completion condition might include browser behavior, migration from stored data, performance on a bounded fixture, or removal of a temporary flag.

I linked tests as receipts rather than treating “tests pass” as the state description. A future reader could start with the claim, then run the evidence.

This kept documentation close to behavior without asking code to contain every historical reason.

The habit scaled from code to decisions

As D4U7 formed, I noticed that delayed group work had the same resumption problem at a larger scale. A chat thread preserved messages like open tabs preserved locations. A meeting recording preserved everything like a terminal log preserved output. Neither offered a compact transition into current understanding.

The four-part personal handoff became a product primitive:

  • Current room state.
  • Evidence and decisions that produced it.
  • Next action and an owner label.
  • Completion or review condition.

The group setting added proposals, dissent, revisions, and permissions. The original insight remained small: continuity requires durable reasoning, not merely durable artifacts.

I did not claim a person was a distributed process. The analogy was unnecessary at this scale. I only acknowledged that memory across time was not perfectly shared, even within one mind.

Tomorrow should not have to become yesterday again

The W93H fix took less than an hour after I wrote the first useful handoff. The time saved was not typing speed. I avoided rebuilding the problem state.

The practice did not eliminate warm-up. Code and evidence still required reading. Some investigations changed enough overnight that the note became obsolete. The improvement was a defined starting point with visible assumptions.

It also made abandonment cleaner. When an experiment no longer justified more time, I could close it with the last known state, the reason for stopping, and the condition that might make it worth reopening. An abandoned branch without that record felt like unfinished obligation. A closed experiment became reusable evidence: the approach failed under these constraints, for these reasons, and its remaining idea lives here. D4U7 later gave “no decision” the same legitimacy. Not every bounded effort needs a triumphant conclusion; it needs an honest terminal state.

I had spent years designing receipts, manifests, revisions, and incident timelines for software. Applying the same care to unfinished thought felt almost embarrassingly obvious.

A stopped task is a partially completed operation. Its code is only part of its state. The reason, evidence, uncertainty, and next safe transition need somewhere durable to live.

Tomorrow's version of me is familiar, authorized, and missing context. A good handoff respects all three facts.