graceful-handoff/CHANGELOG.md
Kjell Tore Guttormsen 192d4403eb feat(graceful-handoff): remove hardcoded push window — push is now unconditional (v3.1.0)
The regime-wide push-window restriction (man–tor 08:00–17:00, fre 08:00–16:00)
was lifted permanently, so SKILL.md no longer gates the push on a weekday/time
window — it would otherwise park a push in the middle of working hours.

Two invariants are unchanged: push is Forgejo only (never GitHub), and push
stays user-triggered (the skill is disable-model-invocation: true). The pipeline
script had no window logic — only its header comment was corrected.

If a future repo needs a window again, reintroduce it as per-repo config, never
as a hardcoded default.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BcNX2QdgmXyLd2Bt6Z25GU
2026-06-24 11:00:10 +02:00

10 KiB
Raw Permalink Blame History

Changelog

All notable changes to graceful-handoff are documented here.

The format is based on Keep a Changelog.

[3.1.0] - 2026-06-24

Changed

  • Removed the hardcoded push window — push is now unconditional, Forgejo only. The regime-wide push-window restriction (mantor 08:0017:00, fre 08:0016:00) was lifted permanently, so SKILL.md no longer gates the push on a weekday/time window — it would otherwise park a push in the middle of working hours. The two other invariants are unchanged: push is Forgejo only, never GitHub, and push stays user-triggered (the skill is disable-model-invocation: true and never auto-pushes outside a user-invoked handoff). handoff-pipeline.mjs had no window logic — only its header comment was corrected. If a future repo needs a window again, reintroduce it as per-repo config, never as a hardcoded default.

[3.0.0] - 2026-06-23

BREAKING

  • Full integration with the STATE.md continuity system. The plugin no longer writes its own NEXT-SESSION-PROMPT.local.md artifact. /graceful-handoff now overwrites the nearest STATE.md (cwd → repo root) with a complete state-of-play in the mandatory format — title + subtitle + a ## 👉 NESTE — START HER block on top, then fixed sections and short history. STATE.md is the one continuity layer; local handover inventions (NEXT-SESSION, HANDOVER.md, ROADMAP.md) are gone.
  • Inverted architecture: the model writes, the script assists. Only the session model has the context to fill the 👉 NESTE block meaningfully — a deterministic git log snapshot never could. scripts/handoff-pipeline.mjs is now a slim, deterministic STATE helper: --plan (resolve nearest STATE.md + classify remote + git facts, read-only), --commit (stage only STATE.md when tracked, plus explicit --also paths — never git add -A), --dry-run. It no longer renders artifacts.
  • All three hooks removed. The Stop auto-trigger, the statusLine hint, and the SessionStart auto-loader are deleted (hooks/ is gone):
    • SessionStart loader was redundant — the global ~/.claude/hooks/session-start.sh already injects the nearest STATE.md.
    • statusLine was dead code — a user's ~/.claude/settings.json statusLine always wins over a plugin's, and it already shows context %.
    • Stop auto-trigger would overwrite a good, model-written STATE.md with a poor snapshot. Removed in favour of a purely manual regime.
  • Removed the model: claude-sonnet-4-6 pin. Writing a self-standing STATE.md is human-facing synthesis → the skill now inherits the session model (Opus-class quality).

Changed

  • Remote-aware STATE policy. STATE.md must never reach a public mirror. The helper classifies the origin remote (github.com or the open/ Forgejo namespace → public → STATE local-only/gitignored; otherwise → private → STATE tracked). The authoritative commit signal is git check-ignore STATE.md; remote_class only drives a leak_warning when the two disagree.
  • SKILL.md is now the operationalised "Session Slutt" ritual: reach a natural stopping point → --plan → write STATE.md → --commit → push only inside the window → fixed closing line.
  • Tests rewritten around --plan/--commit; the no-git add -A regression guard is preserved. Hook tests removed.

Migration from v2.x

No automatic migration. Reinstall to drop the hooks. /graceful-handoff now writes STATE.md instead of a NEXT-SESSION artifact; any stale NEXT-SESSION-*.local.md files can be deleted. STATE.md auto-loads at session start via the global hook — the plugin no longer ships its own loader.

[2.1.0] - 2026-05-01

Fixed

  • Modell-bevisst kontekstvindu i Stop hook (stop-context-monitor.mjs). Tidligere fallback antok 200K-vindu. På Opus 4.7-sesjoner (faktisk 1M-vindu) kunne auto-handoff fyre 57x for tidlig — estimert 70% når reell bruk var ~14%. Erstatter windowSize = payload?.context_window?.context_window_size || 200_000 med en 4-stegs resolution-kjede (resolveContextSource()):
    1. payload.context_window.used_percentage (autoritativ, modell-agnostisk — kilde: direct)
    2. payload.context_window.context_window_size + transcript-estimat (kilde: payload-size)
    3. MODEL_WINDOWS[payload.model.id] + estimat (Opus 4.7=1M, Sonnet 4.6=200K, Haiku=200K — kilde: model-map)
    4. FALLBACK_WINDOW = 1_000_000 + estimat (oppdatert 2026-default — kilde: default-1m)

Changed

  • additionalContext-meldinger fra Stop hook inkluderer nå [kilde: <source>] for innsyn i hvilken resolution-path som ble brukt (direct/payload-size/model-map/default-1m).
  • Inline-kommentar (linje 1422) og README/CLAUDE.md-seksjoner om auto-trigger-mekanikk oppdatert til å beskrive ny kjede.

Tests

  • 6 nye tester i tests/hooks/stop-context-monitor.test.mjs dekker hver path: used_percentage foretrukket, used_percentage trigger med tom transcript, model-map for Opus 4.7 (1M) og Haiku (200K), default 1M-fallback med tomt payload, og null used_percentage faller gjennom til size-pathen. Total: 56 tester (50 + 6).

Open

  • Stop-hook payload-schema er ikke offisielt dokumentert. Det er ikke bekreftet at Stop-payload faktisk inneholder used_percentage eller model.id (statusLine-payload gjør). Hvis ingen av feltene leveres, faller resolveren til default-1m. Smoke-test ved første Opus 4.7-sesjon vil avgjøre hvilken kilde som blir primær.

[2.0.0] - 2026-05-01

BREAKING

  • Hard cut from commands/ to skills/. The plugin now ships a single SKILL.md at skills/graceful-handoff/SKILL.md with disable-model-invocation: true and model: claude-sonnet-4-6. The legacy commands/graceful-handoff.md is deleted. User-invocation /graceful-handoff works as before.
  • Architecture rewrite. The 6-phase prose workflow is replaced by a deterministic Node script scripts/handoff-pipeline.mjs that returns structured JSON. SKILL.md is now a thin orchestration wrapper. Tests run directly against the pipeline without LLM involvement.
  • Removed auto_discover: true from plugin.json (not in documented schema; silently ignored anyway per research/05).

Added

  • Auto-trigger via Stop hook (hooks/scripts/stop-context-monitor.mjs). Estimates context usage from transcript size; at estimated ≥70%, auto-writes the artifact and creates a commit. Push remains user-triggered (separates reversible from irreversible). Lock file at <transcript_dir>/.handoff-lock-<session_id> prevents repeat firing within a session.
  • Context hint via statusLine (hooks/scripts/statusline-monitor.mjs). Reads context_window.used_percentage from payload; prints a hint at 60% and an urgent reminder at 70%. Display-only — never runs git (unsafe per research/03).
  • Auto-load via SessionStart hook (hooks/scripts/session-start-load-handoff.mjs). On source: resume or source: compact, finds NEXT-SESSION-*.local.md (cwd + 3 levels up), injects content via additionalContext, archives the file (*.archived.local.md) to prevent stale-load.
  • Commit-message confirmation gate: pipeline prints message to stderr, reads y/n from stdin (interactive). --auto flag bypasses for hook-driven invocations.
  • New flags: --no-push (commit but don't push), --auto (non-interactive auto-Y), --non-interactive.
  • Pipeline robustness: detached HEAD detection, no-upstream detection, idempotency check (60s cooldown on clean tree), pre-commit hook respect.
  • 36 unit tests across 5 test files (skill-structure, pipeline, statusline-monitor, stop-context-monitor, session-start-load-handoff).

Changed

  • Pipeline staging discipline (CRITICAL). Pipeline now stages ONLY the handoff artifact (and REMEMBER.md/TODO.md if present). Previously used git add -A which scoops up unrelated work-in-progress. The new behavior is enforced by a regression test.
  • allowed-tools is now Bash sub-scoped (Bash(git:*) Bash(node:*) Bash(jq:*) ...) instead of an open Bash. Note: per research/02, this is pre-approval (not restriction) — to actually block tools, project-level deny rules are needed.
  • Plugin model is pinned to claude-sonnet-4-6 (was: inherit from session). Frees Opus 4.7 budget for the next session that the user is actually entering.

Known limitations

  • statusLine placement in hooks/hooks.json is an open assumption (research/03 confirmed statusLine config exists, but exact placement vs settings.json is unverified). Smoke-test required.
  • Token estimation in Stop hook uses chars/3.5 heuristic — may drift ±10% from Claude's internal counting. The 70% threshold is conservatively set.
  • disable-model-invocation: true has open issue #26251; manual smoke-test recommended before relying on it.
  • Auto-execute does not push: irreversible operations remain user-triggered.

Migration from v1.0.0

There is no automatic migration. v2.0.0 is a breaking change.

  1. Reinstall the plugin to pick up skills/ and remove commands/.
  2. The /graceful-handoff slash command works identically from the user's perspective.
  3. The new auto-trigger features activate automatically when the plugin's hooks are loaded.

[1.0.0] - 2026-04-19

Added

  • Initial release with single command /graceful-handoff
  • 6-fase deklarativ workflow: detect → classify → write artifact → update REMEMBER/TODO → commit+push → print copy-paste-prompt
  • Tre handoff-typer: multi-sesjon (ultraplan-prosjekt), plugin-arbeid (marketplace-plugin), enkelt-oppgave (fallback)
  • Default filnavn NEXT-SESSION-PROMPT.local.md; slug-override via første posisjons-argument
  • Flag: --no-commit (skip git), --dry-run (ingen skriving, ingen git-ops)
  • Auto-generert Conventional Commits-melding fra git diff --stat
  • Respekterer pre-commit hooks (secrets, pathguard) — bypasser aldri
  • Tidsbudsjett < 60 sekunder; ingen Agent-delegering, ingen WebSearch
  • 7-seksjons-template for NEXT-SESSION-artefakt (matcher eksisterende konvensjon i llm-security/config-audit)

Notes

  • Auto-discover plugin — marketplace.json-oppføring ikke nødvendig
  • MIT-lisens