ktg-plugin-marketplace/plugins/graceful-handoff/docs/brief-context-window-detection.md
Kjell Tore Guttormsen 40a82ccdb4 fix(graceful-handoff): model-aware context window detection (v2.1.0)
Stop hook fallback antok 200K-vindu. På Opus 4.7 (faktisk 1M) kunne
auto-handoff fyre 5–7x for tidlig — estimert 70% når reell bruk var
~14%. Erstatter enkel fallback med 4-stegs resolution-kjede:

  1. payload.context_window.used_percentage  (autoritativ)
  2. payload.context_window.context_window_size + transcript-estimat
  3. MODEL_WINDOWS[payload.model.id] + estimat
  4. FALLBACK_WINDOW=1_000_000 + estimat (2026-default)

additionalContext-meldinger inkluderer nå [kilde: <source>] for innsyn.
Brief som kilde-artefakt i docs/brief-context-window-detection.md.
6 nye tester (57 totalt). Ingen regresjoner.
2026-05-01 09:08:24 +02:00

144 lines
5.6 KiB
Markdown
Raw 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.

# Brief: Modell-bevisst kontekstvindu i graceful-handoff
**Dato:** 2026-05-01
**Status:** Forslag — ikke implementert
**Trigger:** Bruker oppdaget at Opus 4.7 har 1M kontekstvindu, ikke 200K. Plugin antar 200K i fallback.
## Problem
`hooks/scripts/stop-context-monitor.mjs:23` definerer:
```js
const FALLBACK_WINDOW = 200_000;
```
Logikken (linje 76-77):
```js
const windowSize = payload?.context_window?.context_window_size || FALLBACK_WINDOW;
const pctRaw = estimateUsedPct(transcriptPath, windowSize);
```
Hvis Stop-hook payload ikke leverer `context_window.context_window_size` — eller leverer `0`/`undefined` — beregner hooken brukt prosent mot 200K. På en Opus 4.7-sesjon med faktisk 1M-vindu betyr det:
- Estimat treffer 70% når faktisk bruk er **~14%** (140K av 1M)
- Auto-handoff fyrer 5-7x for tidlig
- Bruker mister kontinuitet i lange sesjoner
`statusline-monitor.mjs` har ikke samme problem — den leser `used_percentage` direkte fra payload og er modell-agnostisk.
## Hvorfor 200K-fallback ble valgt
Kommentar (linje 14-16):
> Token estimation: char_count / 3.5 → approximate tokens. Compares against
> context_window_size from payload (200000 fallback). Approximation is
> known to drift ±10% — 70% threshold is conservative buffer.
Antakelsen ved skriving av v2.0: Claude-modeller har 200K-vindu som standard. Det stemmer ikke lenger.
## Modell-landskap (verifisert 2026-05-01)
| Modell | Kontekstvindu |
|--------|---------------|
| Opus 4.7 | **1M tokens** (standard, ingen long-context premium) |
| Sonnet 4.6 | 1M tokens (1M tier, beta) eller 200K |
| Haiku 4.5 | 200K tokens |
| Eldre Claude 3.x | 200K tokens |
Kilder:
- https://platform.claude.com/docs/en/about-claude/models/whats-new-claude-4-7
- https://platform.claude.com/docs/en/build-with-claude/context-windows
## Løsningsalternativer
### Alt 1 — Bedre fallback-detektering (minimal endring)
Detekter modell fra payload (`payload?.model` eller lignende felt) og map til kontekstvindu:
```js
const MODEL_WINDOWS = {
'claude-opus-4-7': 1_000_000,
'claude-sonnet-4-6': 200_000, // default, kan ha 1M tier
'claude-haiku-4-5-20251001': 200_000,
};
function resolveWindowSize(payload) {
const fromPayload = payload?.context_window?.context_window_size;
if (fromPayload && fromPayload > 0) return fromPayload;
const model = payload?.model || payload?.session?.model;
if (model && MODEL_WINDOWS[model]) return MODEL_WINDOWS[model];
return 1_000_000; // safer default i 2026
}
```
**Pros:** Minimal kode, dekker 95% av tilfellene.
**Cons:** Hard-kodet modell-tabell må vedlikeholdes. Sonnet 4.6 1M-tier er ikke alltid aktiv — kan over-estimere.
### Alt 2 — Foretrekk `used_percentage` fra payload (foretrukket)
Hvis Stop-hook payload har `context_window.used_percentage` (slik statusline-payload har), bruk den direkte og hopp over transcript-estimat helt:
```js
function estimateUsedPct(payload, transcriptPath, windowSize) {
const direct = payload?.context_window?.used_percentage;
if (typeof direct === 'number' && !isNaN(direct)) {
return direct / 100; // already a percent
}
// Fall back to transcript-size estimate
const stat = statSync(transcriptPath);
const tokens = stat.size / CHARS_PER_TOKEN;
return tokens / windowSize;
}
```
**Pros:** Bruker autoritativ kilde når tilgjengelig. Modell-agnostisk.
**Cons:** Krever verifisering av Stop-hook payload-schema — usikkert om feltet alltid er der.
### Alt 3 — Kombinert (anbefalt)
1. Foretrekk `used_percentage` fra payload (Alt 2)
2. Hvis ikke tilgjengelig, bruk `context_window_size` fra payload + transcript-estimat
3. Hvis heller ikke det, prøv modell-mapping (Alt 1)
4. Siste fallback: 1M (oppdatert default for 2026)
Behold 70% terskel — den er prosent-basert og fungerer uavhengig av vindusstørrelse.
## Sekundært designspørsmål
Er fast 70% terskel optimal for både 200K og 1M?
- 200K × 70% = 140K brukt → 60K headroom
- 1M × 70% = 700K brukt → 300K headroom
Det er rimelig argumenterbart at terskelen bør være høyere ved store vinduer (f.eks. 75-80% for 1M-modeller), siden absolutt headroom betyr mer enn relativ. Men auto-compaction og prompt cache TTL er også prosent-baserte fenomener — så en universell 70% er sannsynligvis fortsatt riktig som default. Lavere prioritet enn fallback-fixen.
## Verifisering
Etter implementering, test:
1. **Smoke test:** Opus 4.7-sesjon, kjør til ~50% (statusline viser pct), bekreft at auto-handoff IKKE trigger.
2. **Unit test:** Mock payload uten `context_window`, med `model: 'claude-opus-4-7'`, verifiser at `windowSize` resolver til 1M.
3. **Unit test:** Payload med `used_percentage: 75`, verifiser at funksjonen returnerer 0.75 uansett windowSize.
4. **Regresjon:** Eksisterende tester i `tests/` skal fortsatt passere.
## Scope-vurdering
- **Innenfor:** Fix av `stop-context-monitor.mjs` fallback. Oppdater inline-kommentar (linje 14-16) og README/CLAUDE.md hvis 200K nevnes der.
- **Utenfor:** Endring av terskel-strategi (70% → variabel). Kan vurderes som separat oppgave.
- **Utenfor:** Endring av `statusline-monitor.mjs` (fungerer allerede modell-agnostisk).
## Estimat
- Implementering: ~30 min (én fil + tester)
- Verifisering: ~15 min smoke + 15 min regresjon
- Doc-oppdatering: ~10 min (README, CLAUDE.md, CHANGELOG)
- Total: ~70 min, én sesjon
## Neste skritt (når godkjent)
1. Bekreft Stop-hook payload-schema (har den `used_percentage` eller bare `context_window_size`?)
2. Implementer Alt 3 i `stop-context-monitor.mjs`
3. Oppdater fallback-kommentaren
4. Skriv tester for nye fallback-veier
5. Bump til v2.1.0 (minor — bug-fix + behavioral change)
6. Oppdater CHANGELOG, README, CLAUDE.md, rot-README