graceful-handoff/CHANGELOG.md
Kjell Tore Guttormsen 5e17409275 docs(graceful-handoff): drop the hooks-0 badge (repo-standard BADGE-COUNT)
repo-standard v0.2.0 flagged 6 badges as past the measured inflection of 5,
where a badge row reads as clutter rather than evidence. Removed the
hooks-0 badge: a badge asserting an absence is not something a reader acts
on, and "No hooks" is already stated twice in prose, where it carries its
actual argument.

Kept skill-1 deliberately — with the tests badge already dropped and the
STATE-helper badge non-numeric, it is the only axis the catalog's version
gate can still verify for this plugin.

Gate: 0 ERROR / 0 WARN, 14 checks passed. Docs only, no version bump.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019x1C8tjmB2vUCM9jE668ZF
2026-08-04 11:51:37 +02:00

123 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Changelog
All notable changes to graceful-handoff are documented here.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
## [Unreleased]
### Changed
- **README brought in line with the org repo standard** (`repo-standard` gate, 0 ERROR). Documentation only — no plugin code, version, or behaviour changed. H1 is now the repo name; the opening line is verbatim the forge description (so description == catalog == README is machine-checkable); `## Install` is a top-level heading on the first screen and carries the CLI command `claude plugin install graceful-handoff@ktg-plugin-marketplace` next to `marketplace add`; `## Non-goals` and `## Changelog` sections added.
- **Dropped the static `tests-30` badge.** This forge has no CI runner, so the badge asserted a run nothing verifies. The Testing section now states the command and says plainly that nothing runs it automatically. Note for the catalog: the tests axis no longer has a badge backing it.
- **Fixed two dead `../../README.md` references** inherited from the monorepo (README lines 7 and the marketplace footer) — both pointed outside a standalone repo and 404'd.
- **Dropped the `hooks-0` badge** (6 → 5 badges, clearing the `repo-standard` BADGE-COUNT warning). A badge asserting an absence is not something a reader acts on, and "No hooks" is already stated in prose where it carries its actual argument. The `skill-1` badge was deliberately kept: it is the only axis the catalog's version gate can still verify for this plugin.
## [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](https://github.com/anthropics/claude-code/issues/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