feat(graceful-handoff)!: integrate with STATE.md continuity system (v3.0.0)
BREAKING: replace the NEXT-SESSION artifact + 3 hooks with a STATE.md-centric, skill-only design. /graceful-handoff now overwrites the nearest STATE.md (with the mandatory 👉 NESTE block) instead of writing a separate handover file. - Remove hooks/ entirely: Stop auto-trigger (operator choice), SessionStart loader (redundant with global session-start.sh), statusLine hint (dead — user settings win). - Invert the pipeline: the model writes STATE.md (only it has the context for 👉 NESTE); handoff-pipeline.mjs becomes a slim deterministic helper (--plan / --commit / --dry-run). - Remote-aware policy: STATE.md tracked on private remotes, local-only (gitignored) on public/open mirrors. Authoritative signal: git check-ignore STATE.md. - SKILL.md rewritten as the Session-Slutt ritual; dropped the Sonnet model pin. - Docs (README, CLAUDE.md, CHANGELOG), plugin.json 2.1.0→3.0.0, .gitignore cleanup. - Tests rewritten for --plan/--commit; no-`git add -A` regression preserved. 30/30 green. Release-cut (tag v3.0.0 + catalog ref bump) pending — separate gated action. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019SiKr4c6GAzQH5n6E6f5NA
This commit is contained in:
parent
a6f3ad4e93
commit
2c4e5e425b
18 changed files with 694 additions and 1656 deletions
95
CLAUDE.md
95
CLAUDE.md
|
|
@ -1,65 +1,78 @@
|
|||
# graceful-handoff (v2.1)
|
||||
# graceful-handoff (v3.0)
|
||||
|
||||
Auto-trigger sesjonsoverlevering ved kontekst-terskel, med manuell `/graceful-handoff` som backup. Skill-arkitektur (`disable-model-invocation: true`), deterministisk JSON-pipeline, og tre hooks som dekker hint, auto-eksekvering, og auto-load.
|
||||
Én-kommandos sesjonsoverlevering inn i **STATE.md-kontinuitetssystemet**. `/graceful-handoff`
|
||||
når et naturlig stoppunkt, overskriver nærmeste `STATE.md` med en komplett state-of-play
|
||||
(obligatorisk «👉 NESTE — START HER»-blokk øverst), og committer per remote-policy. Skill-only
|
||||
arkitektur (`disable-model-invocation: true`) + ett slankt deterministisk hjelpeskript. **Ingen hooks.**
|
||||
|
||||
## Når brukes den
|
||||
## Hva den gjør
|
||||
|
||||
- **Automatisk:** Stop hook fyrer ved estimert ≥70% kontekst-bruk. Skriver artefakt + commit. Push gjenstår manuell.
|
||||
- **Manuelt:** `/graceful-handoff` ved 60-70% (eller når som helst). statusLine viser hint ved 60% og urgent ved 70%.
|
||||
- **Ny sesjon:** SessionStart hook auto-leser handoff-fil ved `source: resume` eller `source: compact` og injiserer i kontekst.
|
||||
`/graceful-handoff` er operasjonaliseringen av den globale «Session Slutt»-rituelen, sentrert
|
||||
på STATE.md (ett av tre kontinuitets-lag: `STATE.md` + auto-memory `MEMORY.md` + `CLAUDE.md`).
|
||||
Den skriver IKKE lenger en egen `NEXT-SESSION`-artefakt — det var nettopp den typen lokale
|
||||
handover-påfunn regimet forbyr. STATE.md ER overleveringen.
|
||||
|
||||
## Komponenter
|
||||
- **Manuelt, når du vil:** `/graceful-handoff`. Sesjonen avslutter ved første naturlige punkt og
|
||||
etterlater en selvtilstrekkelig STATE.md.
|
||||
- **Ny sesjon:** den globale `~/.claude/hooks/session-start.sh` injiserer nærmeste STATE.md
|
||||
automatisk. Pluginen trenger ingen egen auto-load.
|
||||
|
||||
## Arkitektur — modellen skriver, skriptet assisterer
|
||||
|
||||
Bare sesjonsmodellen har konteksten til å fylle «👉 NESTE»-blokken meningsfullt. Et deterministisk
|
||||
`git log`-snapshot kan det aldri. Derfor er ansvaret invertert mot v2:
|
||||
|
||||
| Fil | Rolle |
|
||||
|-----|-------|
|
||||
| `skills/graceful-handoff/SKILL.md` | Slash-command-handler. Frontmatter: `disable-model-invocation: true`, `model: claude-sonnet-4-6`, sub-scoped `allowed-tools`. Body orkestrerer pipeline-skriptet. |
|
||||
| `scripts/handoff-pipeline.mjs` | Deterministisk Node-skript. Klassifiserer handoff-type, skriver artefakt, håndterer commit-bekreftelse, returnerer JSON. |
|
||||
| `hooks/scripts/statusline-monitor.mjs` | Display-only hint. Leser `context_window.used_percentage` fra payload. |
|
||||
| `hooks/scripts/stop-context-monitor.mjs` | Estimerer kontekst fra transcript-størrelse. Spawner pipeline ved ≥70%. |
|
||||
| `hooks/scripts/session-start-load-handoff.mjs` | Auto-leser NEXT-SESSION-fil ved resume/compact, archiverer etter load. |
|
||||
| `hooks/hooks.json` | Registrerer alle tre hooks + statusLine. |
|
||||
| `skills/graceful-handoff/SKILL.md` | Rituelet, modell-drevet (full kontekst). Frontmatter: `disable-model-invocation: true`, **ingen `model:`-pin** (arver sesjonsmodell — STATE.md er human-facing syntese → Opus-kvalitet), sub-scoped `allowed-tools` inkl. `Write`. |
|
||||
| `scripts/handoff-pipeline.mjs` | Slank deterministisk STATE-hjelper. `--plan` (resolver nærmeste STATE.md + klassifiser remote + git-fakta, read-only), `--commit` (stager KUN STATE.md når tracked + eksplisitte `--also`-stier; aldri `git add -A`), `--dry-run`. Returnerer JSON. Testbar uten LLM. |
|
||||
|
||||
## Arkitektur-prinsipper
|
||||
Rituelet (SKILL.md): nå naturlig stoppunkt → `--plan` → skriv/overskriv STATE.md i fast format
|
||||
→ `--commit` → push kun i vindu → fast avslutningslinje.
|
||||
|
||||
- **Hard cut fra commands/ til skills/.** v2.0 har ingen bakoverkompatibilitet.
|
||||
- **disable-model-invocation: true.** Modellen kan IKKE invokere skill-en autonomt — bruker trigger manuelt eller hooks kaller pipeline-skriptet direkte.
|
||||
- **Pipeline er deterministisk.** Tester kjører mot pipeline-skriptet uten LLM. Driftvariasjoner mellom Opus/Sonnet/Haiku elimineres for selve handoff-arbeidet.
|
||||
- **Push aldri automatisk.** Reversibel handling (commit) auto-eksekveres; irreversibel (push) krever bruker.
|
||||
- **Eksplisitt staging.** Pipeline stager kun artefakten (+ REMEMBER.md/TODO.md hvis de finnes). ALDRI `git add -A` — det scoopper opp ubeslektet WIP. Regression-test håndhever dette.
|
||||
## STATE.md-format (ufravikelig)
|
||||
|
||||
## Auto-trigger-mekanikk
|
||||
`# STATE — <navn>` + undertittel → **`## 👉 NESTE — START HER`** ØVERST (hvor vi er + nummererte
|
||||
neste steg + pekere til hva som må leses) → faste seksjoner (oppdrag/kjøremodus, gotchas,
|
||||
push-status, repo/env) + kort historikk UNDER. Maks ~60 linjer. Overskriv, ikke append.
|
||||
|
||||
Claude Code eksponerer ikke real-time kontekst-prosent direkte til Stop hook (Anthropic har closed feature requests #16988, #27969, #34340). v2.1 bruker en **4-stegs resolution-kjede** (`resolveContextSource()` i `stop-context-monitor.mjs`):
|
||||
## Remote-policy (STATE må aldri nå et offentlig speil)
|
||||
|
||||
1. `payload.context_window.used_percentage` — autoritativ, modell-agnostisk (kilde: `direct`)
|
||||
2. `payload.context_window.context_window_size` + `chars/3.5`-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`)
|
||||
Hjelperen klassifiserer `origin`:
|
||||
- `github.com` eller `open/`-Forgejo-namespace → **public** → STATE.md local-only (gitignored), committes aldri.
|
||||
- ellers (privat Forgejo `ktg/…`) → **private** → STATE.md tracked + committet.
|
||||
|
||||
Ved ≥ 70% (estimert): spawn pipeline med `--auto --no-push --non-interactive`. additionalContext-meldingen inkluderer `[kilde: <source>]` for innsyn.
|
||||
Den autoritative commit-beslutningen er `git check-ignore STATE.md`; `remote_class` driver kun et
|
||||
`leak_warning` når de to er inkonsistente (offentlig remote, men STATE.md ikke gitignored).
|
||||
|
||||
Lock-fil `<transcript_dir>/.handoff-lock-<session_id>` hindrer repeat-firing innen samme sesjon.
|
||||
**Denne repoen har `open/`-remote → STATE.md er gitignored (local-only).** Plugin-koden er offentlig;
|
||||
state-of-play er det ikke.
|
||||
|
||||
## Eksplisitt staging (ufravikelig)
|
||||
|
||||
`--commit` stager KUN STATE.md (+ eksplisitte `--also`-stier). ALDRI `git add -A` — det scoopper opp
|
||||
ubeslektet WIP. Regresjonstest håndhever dette. Pre-commit hooks respekteres uten `--no-verify`.
|
||||
|
||||
## Tester
|
||||
|
||||
```bash
|
||||
node --test plugins/graceful-handoff/tests/
|
||||
node --test 'tests/**/*.test.mjs'
|
||||
```
|
||||
|
||||
36+ tester på tvers av 6 test-filer. Stop hook-tester bruker stub pipeline (genererer en mid-test fake `scripts/handoff-pipeline.mjs` i temp dir) for å unngå reelle git-operasjoner mot marketplace-repoet.
|
||||
|
||||
## Tidsbudsjett
|
||||
|
||||
< 60 sekunder totalt for hele pipelinen. Pipeline-skriptet er testbart med `node:test` uten LLM-kall.
|
||||
|
||||
## Åpne antakelser (verifiseres ved smoke-test)
|
||||
|
||||
- **statusLine-plassering i `hooks/hooks.json`** vs `~/.claude/settings.json`. Vi setter den i hooks.json som første-prioritet design.
|
||||
- **Token-estimering ±10%** mot Claude's reelle telling.
|
||||
- **Issue #26251** (`disable-model-invocation: true` regression). Smoke-test at `/graceful-handoff` fungerer etter installasjon.
|
||||
30 tester på tvers av 3 filer (`skill-structure`, `scripts/handoff-pipeline`, `plugin-manifest`).
|
||||
Pipelinen er deterministisk og testes uten LLM-kall: `--plan`/`--commit`-JSON, nærmeste-STATE-resolusjon,
|
||||
remote-klassifisering, staging-disiplin (no-`git add -A`-regresjon), gitignored-STATE-skip, detached-HEAD,
|
||||
`--dry-run`.
|
||||
|
||||
## Versjonering
|
||||
|
||||
- v1.0.0 (2026-04-19): initial declarative command
|
||||
- v1.0.0 (2026-04-19): deklarativ command, NEXT-SESSION-artefakt
|
||||
- v2.0.0 (2026-05-01): skill-arkitektur + JSON-pipeline + 3 hooks + auto-trigger (BREAKING)
|
||||
- v2.1.0 (2026-05-01): modell-bevisst kontekstvindu — 4-stegs resolution-kjede (used_percentage → payload-size → model-map → 1M default). Fikser for-tidlig auto-handoff på Opus 4.7
|
||||
- v2.1.0 (2026-05-01): modell-bevisst kontekstvindu (4-stegs resolution-kjede)
|
||||
- v3.0.0 (2026-06-23): **STATE.md-integrasjon (BREAKING).** Fjernet NEXT-SESSION-artefakt + alle 3 hooks; invertert pipeline (modellen skriver STATE.md, skriptet assisterer); remote-aware tracked/local-only-policy; fjernet Sonnet-pin.
|
||||
|
||||
## Release (polyrepo — egen gated handling)
|
||||
|
||||
En versjonsbump er ikke fullført før: (1) `v3.0.0`-tag laget + pushet i denne repoen, OG (2)
|
||||
katalogens `ref` bumpet til samme tag med `check-versions.mjs` grønn. Bruk
|
||||
`../catalog/scripts/release-plugin.mjs graceful-handoff <versjon>` (atomisk). Krever push-vindu + operatør-go.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue