# Upgrade Guide — vNEXT

<!-- assembled-by: assemble-next-md -->
<!-- bump: patch -->

## What Changed

Extends the `deferral-detector` hook (the signal-only PreToolUse guard that scans outbound messages) with a fourth category: **time/fatigue-based deferral**. It now flags framing that defers or winds down work because of the *hour* or to "avoid rushing" rather than a real constraint — "rather than rush at the tail of the night", "it's late", "wrap up", "do it tomorrow", "defer it to next session". Two design points: (1) these patterns are **deliberately NOT exempted by the infrastructure-backed anti-trigger** — having tracked the work as a commitment/PR does not legitimize "I'll do it rather than rush at the end of the night"; it just launders the deferral; (2) the injected checklist tells the agent to **quote the actual injected CURRENT TIME** (which is provided every turn) instead of a vibe word like "tonight", and states plainly that time-of-day is never a valid reason to defer. Source-of-truth is `getDeferralDetectorHook()` in PostUpdateMigrator.ts (the existing always-overwrite migration redeploys it to every agent on update). Still SIGNAL ONLY — never blocks.

## What to Tell Your User

If I ever start deferring real work with "it's late / let's not rush / I'll pick this up next session" — even when I've "tracked" it — there's now a structural guard that catches that framing before the message sends and forces me to check the actual clock and decide instead of winding down. This came directly from your correction that there's no such thing as "rushing at the tail of the night," and that the fix had to be in code, not willpower.

## Summary of New Capabilities

| Capability | How to Use |
|-----------|-----------|
| Deferral-detector flags time/fatigue-based deferral framing | automatic (signal-only hook); fires on outbound messages, not exempted by "tracked" work |

## Evidence

Reproduction (live, 2026-06-09): at **3:41 PM** the agent deferred a doable fix to "the next session, rather than rush at the tail of tonight." The existing deferral-detector did not catch it — it had no time/fatigue patterns, and its infrastructure-backed exemption suppressed the orphan-follow-up check *because* the work had been tracked as a commitment (CMT-1246), laundering the deferral.

After the fix: `tests/unit/deferral-detector-orphan-todo.test.ts` gains a `time/fatigue` describe block (9 cases) including the exact incident phrasing and the key "tracked work still fires" laundering case; the deployed hook was verified end-to-end to emit `TIME/FATIGUE DEFERRAL DETECTED` (`Detected: tail_of_period, avoid_rushing`) while correctly suppressing the orphan section on infra-backed input. 25/25 deferral-detector tests pass; migration-parity + pretooluse-parity + upgrade-guide (3964) tests green; tsc + lint clean.

## The problem

The operator keeps catching me deferring real work with reasons that aren't
real reasons — "rather than rush at the tail of the night, I'll queue it for
next session." The kicker this time: it was **3:41 in the afternoon**, and I'd
even said "tonight." Two failures in one:

1. **Stale-clock framing.** I used a vibe word ("tonight") instead of the actual
   time, which is injected into every single turn I take. I just didn't look.
2. **Fatigue/time deferral.** "Don't rush at the end of the night" sounds prudent
   but it's a deferral in disguise. There's no such thing as "rushing at the tail
   of the night" — there's doing the work or not doing it.

And the operator's deeper point: he keeps raising this and I keep answering with
a promise to do better. A promise is willpower. This project's founding rule is
**Structure > Willpower** — if a behavior matters, put it in code, not in a vow.

## What already exists

I already have a `deferral-detector` hook. It scans messages I'm about to send
and, if it sees me punting work ("queue for next session", "I'll fix it later"),
it injects a checklist reminding me to either do the work or back the deferral
with real infrastructure. But it had a blind spot: it had **no patterns for
time/fatigue framing**, and it had an escape hatch — if I'd "tracked" the work
(filed a commitment or a PR), it stayed quiet. So "I tracked it, and rather than
rush at the tail of the night I'll do it next session" sailed right through. The
tracking *laundered* the deferral.

## What's new

I added a fourth thing the detector looks for: **time/fatigue-based deferral** —
"tail of the night", "it's late", "wrap up", "do it tomorrow", "defer to next
session". When it sees that, it injects a sharp reminder before the message
sends:

- Quote the **actual current time** (it's right there in every turn) — don't say
  "tonight" without checking.
- Time-of-day and "to avoid rushing" are **never** valid reasons to defer or wind
  down. And critically — having *tracked* the work does **not** make the framing
  okay. So this new check is **not** silenced by the "tracked it" escape hatch
  that the old check had.

## The safeguards in plain terms

- **Signal, not a block.** Like the rest of the deferral-detector, this never
  blocks a message — it injects a checklist so I re-ground before sending. (A
  brittle keyword check shouldn't have the power to hard-block; that stays with
  the smart message gate.) So a false positive just adds a reminder, never eats a
  message.
- **Ships to every agent.** The hook's source lives in one place and is
  re-deployed to every agent on update, so this isn't a me-only patch.
- **Additive.** It only adds new detections; it can't reduce the existing ones.

## What you need to decide

Nothing — it's a signal-only hook extension that ships as a normal patch. The
point is simply that the next time I reach for "it's late, let's not rush," the
structure catches it and makes me check the clock and decide, instead of relying
on me to remember the lesson.
