docs: skills simuler and forbedre, README, changelog and contribution guide

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-11-11 14:42:04 +01:00
commit 2669759f5a
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q
6 changed files with 643 additions and 2 deletions

68
BIDRA.md Normal file
View file

@ -0,0 +1,68 @@
# Bidra med en forbedring
Modellen er en første versjon, og notatet *Den dynamiske rettsstaten* er skrevet som en invitasjon til videre arbeid.
Har du forbedret modellen, rettet en feil eller prøvd den mot data, tas det gjerne imot. Denne siden sier hvordan du
sender det, og hva et bidrag må ha for at det kan vurderes.
## Slik sender du det
Repositoryet ligger på en egen Forgejo-server der utenforstående ikke kan registrere seg, så bidrag kommer på
e-post: **hello@fromaitochitta.com**.
Send:
1. **Endringen**, som en patch eller som de endrede filene.
- Har du klonet repositoryet med git, lag patchen med `git format-patch origin/main` (én fil per commit).
- Har du en arbeidskopi fra pluginen (`rettsstat-modell/`), kan du legge den i git før du endrer noe
(`git init`, `git add -A`, `git commit -m "utgangspunkt"`) og lage patchen med `git format-patch -1` etter at
endringen er committet. Uten git: send filene du har endret eller lagt til, med stien i kopien.
2. **Utskriften fra kontrollen** på modellen med endringen:
`python3 modell/kjor.py kontroll` i arbeidskopien eller klonen (den fulle, ikke `--rask`).
3. **Scenariofilene** som viser hva endringen gjør, og gjerne sammendragene kjøringene skrev.
4. **En kort forklaring**: hva endringen gjør, hvorfor (hypotesen, gjerne med kilde), og hva kjøringene viser.
## Hva et bidrag må ha
- **Én mekanisme eller én endring om gangen.** To endringer i samme bidrag gjør det umulig å si hva som ga hvilket
utslag.
- **For en utvidelse** (en ny mekanisme i `modell/utvidelser/`): et grensetilfelle som gjenskaper kjernen eksakt
(største avvik `0.0`), og en test som viser det. `grensetilfelle()` og grensesnittet står i `docs/utvidelser.md`;
testen av grensetilfellet følger med automatisk, men legg gjerne til en test av det mekanismen gjør utenfor
grensetilfellet. Kontrollen skal si «bit for bit som notatet» eller «innenfor toleranse».
- **For en endring i kjernen** (`modell/kjerne/`): listen over notatets resultater som flytter seg (kontrollen sier
hvilke datafiler og utskrifter, og hvor mye), hvilken figur eller tabell i notatet de hører til
(`docs/modellkart.md`, del (d)), og hvorfor det er ment. Kjernen er en kopi av notatets kode, så en endring der
må også inn i notatets repository før den kan tas inn i pluginen.
- **Ingen persondata og ingen data fra enkeltsaker.** Modellen brukes på kategorier og aggregerte tall. Data til
kalibrering må være aggregerte og ha en oppgitt kilde.
- **Påstander bygger på kjøringer.** Et bidrag som sier at modellen «gir» noe, har med kjøringen som viser det.
## Det som er særlig velkomment
Veiplanen i avsnitt 10 i notatet har åtte punkter. Disse kan gjøres i modellen:
- **Kalibrering mot norske data** (punkt 5), blant annet politiets metningsnivå `K_sat` per sakstype, virkningen av
ulike reaksjonsformer og om det finnes rekrutteringsterskler i bestemte kategorier.
- **Estimering av faktisk reaktivitet og forsinkelse** i budsjett- og prioriteringsprosessene, og av
stabilitetsgrensen for en inkrementell regel (punkt 2).
- **En kjedemodell med kø og frafall i alle fire ledd**, flere sakstyper, ulike behandlingstider og tilbakeløp
(punkt 3). I dag har bare domstolen kø.
- **Simuleringer med målestøy, skjevhet og parameterusikkerhet** (punkt 4). I dag antar alle simuleringene et
feilfritt estimat.
- **Kostnadsfunksjoner i kroner** og en nytte-kostnadsvurdering av tiltakene, med forebygging som alternativ
(punkt 6).
- **En romlig versjon** med forskyvning mellom distrikter, og en modellprediktiv styring av hele tiltaksvektoren
(punkt 8).
Punkt 1 (flaskehalsdiagnose av hele kjeden på norske tall) og punkt 7 (beslutningsrettigheter, hjemler og
budsjettmekanikk) er ikke modellkode, men innspill til dem tas også imot. Det samme gjelder rettelser, også små.
## Lisens
Bidrag tas inn under MIT-lisensen, som resten av pluginen (`LICENSE`). Ved å sende et bidrag sier du deg enig i det,
og i at du har rett til å gi det under den lisensen.
## Hva du kan vente deg
Dette er et privat prosjekt uten fast bemanning. Det er ikke lovet noe svar innen en bestemt tid, og ikke at et
bidrag blir tatt inn. Bidrag som følger punktene over, er lettest å vurdere.

30
CHANGELOG.md Normal file
View file

@ -0,0 +1,30 @@
# Changelog
All notable changes to this project will be documented in this file.
## 0.1.0 — 2026-11-11
Første versjon.
- Fire ferdigheter på norsk: `diagnose` (leddet som binder, tiltakstype og kapasitetsbehov fra egne tall), `forlop`
(stabilitetssjekk og forløp måned for måned), `simuler` (fra «hva om …» til scenariofil, kjøring, tabell og figur)
og `forbedre` (arbeidskopi, modellkart, utvidelser med grensetilfelle og kontroll av hva en endring flytter).
- Modellen bak notatet *Den dynamiske rettsstaten*: `modell/kjerne/` har uendrede kopier av `sim.py`, `diagnose.py`
og `forlop.py` fra notatets repository ved commit 2badc25, låst med sha256 i `modell/kjerne/KILDE.json`.
- `modell/kjor.py`: én inngang for alle kommandoene (`diagnose`, `forlop`, `scenario`, `notatet`, `kontroll`,
`miljo`, `arbeidskopi`), bare standardbiblioteket. Den finner en Python med numpy og scipy, og installerer dem bare
i en egen mappe etter `miljo --opprett`.
- `kontroll`: sammenligner kjernen, diagnosen, forløpet og en full kjøring av notatets simulering med fasiten (22
datafiler og utskriftene), og sier om modellen regner bit for bit som notatet, innenfor toleranse eller er endret.
- Scenariokjøreren med scenarioformat på norsk (`docs/scenarioformat.md`): alle fem simulatorene i kjernen,
overstyring av parameterne, beslutningsregler, sjokk, tiltak og sveip over én eller to parametere. Ut: sammendrag,
CSV per kjøring og `resultat.json` med alle parametere, versjoner og sjekksummer.
- 21 scenariofiler som gjenskaper 20 av notatets 22 datafiler (de to siste er analytiske), og fem scenarioer notatet
ikke har figur for.
- Utvidelser ved siden av kjernen, med regelen fra notatet om et grensetilfelle som gjenskaper kjernen eksakt.
Gjennomført eksempel: `paadrag_tidsserie` (pådraget følger en tidsserie i stedet for ett varig sjokk). Mal i
`docs/utvidelser.md`.
- `arbeidskopi`: en kopi av modellen brukeren eier og kan endre, også kjernen.
- Dokumentasjon: inndata, scenarioformat, modellkart (ligning → funksjon → parameter), utvidelser og forbehold.
Eksempelfiler: stiliserte tall som gjenskaper avsnitt 9.5, og offentlige norske tall for 2025.
- `BIDRA.md`: hvordan en forbedring sendes tilbake.

View file

@ -18,8 +18,13 @@ justice chain (mostly non-programmers) and researchers. The note and its code li
- `modell/kjerne/`: `sim.py`, `diagnose.py`, `forlop.py`, unmodified copies from the note's repo, pinned by sha256 in
`modell/kjerne/KILDE.json`. numpy and scipy pinned in `modell/requirements.txt` (as the note).
- `fasit/`: reference output (22 data files, printouts) that `kontroll` compares against.
- `docs/`: `inndata.md`, `modellkart.md`, `forbehold.md` (and later `scenarioformat.md`, `utvidelser.md`), Norwegian.
- `eksempler/`: `eksempel_domstol.json` (stylized), `norge_2025.json` (public Norwegian figures).
- `modell/scenario.py` (scenario runner over the core's five simulators), `modell/kontroll.py` (reproduction check),
`modell/arbeidskopi.py` (copies the model to a folder the user owns), `modell/utvidelser/` (mechanisms outside the
core; each must reproduce the core exactly in a limit case).
- `docs/`: `inndata.md`, `scenarioformat.md`, `modellkart.md`, `utvidelser.md`, `forbehold.md`, Norwegian. The test for
extensions reads the template in `utvidelser.md` between the markers `<!-- mal:start -->` and `<!-- mal:slutt -->`.
- `eksempler/`: `eksempel_domstol.json` (stylized), `norge_2025.json` (public Norwegian figures), `scenarioer/`
(five scenarios, and `notatet/` with the files that regenerate the note's data files).
## Conventions
- **Never edit `modell/kjerne/`.** It is synced from the note's repo: copy the three files at a given commit, update

183
README.md Normal file
View file

@ -0,0 +1,183 @@
# dynamisk-rettsstat
Plugin for Claude som kjører modellen i Den dynamiske rettsstaten på egne tall: finn leddet som binder, følg tiltaket over tid, simuler egne scenarioer og endre modellen.
Notatet *Den dynamiske rettsstaten* har en modell av straffesakskjeden: hvor den binder, hva slags tiltak det krever,
og hva som skjer over tid. Med denne pluginen kan du bruke modellen ved å snakke med Claude, uten å programmere: legg
inn tall per ledd, eller spør «hva om …», og få svaret med modellens egne tall og forbehold. Den er laget for dem som
arbeider i straffesakskjeden og for forskere som vil prøve, etterprøve eller forbedre modellen.
Prinsippet bak notatet: «Innsatsen for å håndheve lover og regler bør løpende stå i forhold til hvor mye, og hvor
alvorlig, de faktisk brytes.» Straffebud og strafferammer ligger fast.
## Install
I Claude Code:
```bash
claude plugin marketplace add https://git.fromaitochitta.com/open/ktg-plugin-marketplace.git
claude plugin install dynamisk-rettsstat@ktg-plugin-marketplace
```
I Claude Cowork: last ned repositoryet som zip fra Forgejo-siden (`https://git.fromaitochitta.com/open/dynamisk-rettsstat`)
og last det opp som plugin.
Det som trengs:
- **Python 3.** Flaskehalsdiagnosen trenger ikke noe mer.
- **numpy og scipy** for forløpet over tid, simuleringene og kontrollen. Mangler de, spør Claude før noe installeres,
og installerer dem da fra PyPI i en egen mappe for pluginen (krever internett). Ingenting installeres uten at du
sier ja.
Status: prøvd i Claude Code. Ikke prøvd i Cowork ennå.
## Hva du kan gjøre med den
Pluginen har fire ferdigheter. Du trenger ikke kunne navnene: si hva du vil, så velger Claude riktig ferdighet.
Eksemplene under er virkelige svar fra pluginen, kortet ned.
### Finn leddet som binder (`diagnose`)
Du sier: *«Finn flaskehalsen i straffesakskjeden. Her er tallene våre for saker inn, kapasitet og restanse per ledd.»*
Claude spør etter det som mangler, viser tallene slik de er forstått, og regner når du har sagt ja. Med eksempeltallene:
```
Ledd Utnyttelse Saksbeh.tid Mål Restansevekst/mnd
Politi 0,86 1,7 2,0 0
Påtale 0,88 1,2 1,5 0
Domstol 1,28 5,6 3,0 29
Kriminalomsorg 0,90 1,5 2,0 0
Skranken som binder: Domstol (utnyttelse 1,28, restanse 589 mot mål 316; vekst: innstrømning minus kapasitet).
...
Kapasitet: (0,80 x 134,3 + 273/24) / 0,95 = 125,1 saker/mnd, det vil si 19 % mer.
```
Svaret har tiltakene i rekkefølgen utnytt leddet, led saker utenom, utvid, etter *Theory of Constraints*.
### Følg tiltaket over tid (`forlop`)
Du sier: *«Hva skjer måned for måned hvis vi følger anbefalingen? Tåler styringen forsinkelsen?»* Med samme tall:
```
Kritisk forsinkelse: 7,2 mnd. Forsinkelsen er kortere, så styringen er stabil (margin 4,2 mnd).
...
- nå: bestill 19 % mer kapasitet
- om 12 mnd: bestill 12 % mer kapasitet
```
Deretter en tabell med kapasitet, andel ledet utenom, restanse, saksbehandlingstid, politiinnsats, kriminalitet og
tillit, med og uten tiltak, og hva det betyr for leddene etter.
### Kjør modellen med egne forutsetninger (`simuler`)
Du sier: *«Hva om restansen avvikles over 6, 12, 24 eller 48 måneder i stedet for 24 i den koordinerte regelen?»*
Claude beskriver scenarioet med ord, kjører det når du har sagt ja, og viser nøkkeltallene. Utdrag:
```
| Nøkkeltall | T_clear=6 | T_clear=12 | T_clear=24 | T_clear=48 | T_clear=96 | T_clear=inf |
|-----------------------------------------------------------|----------:|-----------:|-----------:|-----------:|-----------:|------------:|
| Kriminalitet K, gjennomsnitt fra mnd 12 | 1,093 | 1,096 | 1,098 | 1,102 | 1,111 | 1,128 |
| Saksbehandlingstid i domstolen, lengste (mnd) | 8,0 | 8,1 | 8,3 | 8,5 | 8,6 | 8,8 |
| Kapasitet, høyeste (1,00 = ved start) | 1,91 | 1,53 | 1,31 | 1,19 | 1,10 | 1,07 |
| Kapasitetsår over utgangsnivået | 6,28 | 4,66 | 3,52 | 2,22 | 1,21 | 0,88 |
```
Parameterne er notatets stiliserte verdier, og tallene viser modellens dynamikk, ikke prognoser; det står i hvert
svar. Hver kjøring skriver et sammendrag, tidsseriene som CSV og alle parametere slik de ble brukt. Claude tilbyr en
figur laget av de samme tallene. Pluginen har fem ferdige scenarioer, og 21 scenariofiler som lager notatets
figurgrunnlag på nytt.
### Forbedre modellen (`forbedre`)
Du sier: *«Jeg vil legge til en mekanisme i modellen»* eller *«Jeg vil endre en ligning og se hva det gjør med
notatets resultater.»* Claude lager en kopi av modellen som du eier, finner ligningen i modellkartet, gjør endringen
sammen med deg og kjører kontrollen. Uendret modell gir `Nivå: bit for bit som notatet.` Her er kjernen i en kopi
endret slik at frafallet fra domstolskøen er 0,02 i stedet for 0,01 per måned:
```
1. Kjernen: endret fra notatet (https://git.fromaitochitta.com/open/den-dynamiske-rettsstaten @ 2badc25): sim.py er endret.
...
4. Full kjøring: 11 av 22 datafiler like byte for byte med notatet; utskriften endret.
kjede_s2.dat (endret): største absolutte avvik per kolonne: K 9,5e-03, U 2,8e-03, L 8,4e-03, T 2,8e-02, Q 1,8e+00, tauD 1,7e+01
...
Nivå: endret: Kjernen, forlop, Full kjøring.
Dette er en arbeidskopi, så det er en opplysning, ikke en feil: detaljene over viser hvilke av notatets resultater som har flyttet seg, og hvor mye.
```
## Prøv uten egne tall
To eksempelfiler følger med. Si for eksempel *«Prøv flaskehalsdiagnosen på eksempeltallene»*:
- **Stiliserte tall** (`eksempler/eksempel_domstol.json`): modellens egne tall, ikke norske. Domstolen binder, og
svaret gjenskaper avsnitt 9.5 i notatet: utnyttelse 1,28 og 19 % mer kapasitet.
- **Offentlige norske tall for 2025** (`eksempler/norge_2025.json`): politi og påtale 1,09, tingrett 1,04,
lagmannsrett 0,88 og fengsel 1,09. Flere av tallene er anslag, og kildene står i fila. Forbeholdene står i
[docs/forbehold.md](docs/forbehold.md).
## Forholdet til notatet
Notatet, simuleringskoden og PDF-ene ligger i
[den-dynamiske-rettsstaten](https://git.fromaitochitta.com/open/den-dynamiske-rettsstaten).
- Kjernen i `modell/kjerne/` er uendrede kopier av notatets `sim.py`, `diagnose.py` og `forlop.py` ved commit 2badc25,
låst med sha256 i `modell/kjerne/KILDE.json`. En test feiler hvis en av dem endres.
- Kontrollen kjører hele notatets simulering og sammenligner med notatets 22 datafiler og utskriftene. Målt
2026-11-11 med Python 3.14.0, numpy 2.5.4 og scipy 1.18.1: alle 22 datafilene er like byte for byte.
Med andre versjoner av numpy og scipy sier kontrollen om tallene er like innenfor én enhet i siste siffer.
- Scenariokjøreren kaller kjernen uendret. Scenariofilene i `eksempler/scenarioer/notatet/` gjenskaper notatets
datafiler, og testene sammenligner dem med fasiten.
## Forbedre modellen selv
Modellen er en første versjon, og notatet er skrevet som en invitasjon til videre arbeid. Pluginen er bygd for at du
skal kunne endre den:
- **Arbeidskopi.** Endringer gjøres i en kopi av modellen i din egen mappe (`rettsstat-modell/`), ikke i pluginen,
som byttes ut når den oppdateres. Ferdighetene bruker kopien når mappa du jobber i, har en.
- **Modellkart.** [docs/modellkart.md](docs/modellkart.md) går fra notatets ligninger til funksjonene og
parameterne i koden, med status for hver ligning.
- **Utvidelser med grensetilfelle.** En ny mekanisme legges ved siden av kjernen, med en verdi der den forsvinner og
modellen gir nøyaktig kjernens tall. Regelen er notatets egen. Mal og et gjennomført eksempel står i
[docs/utvidelser.md](docs/utvidelser.md).
- **Kontrollen** sier etter hver endring om notatets resultater står fast, eller hvilke som har flyttet seg og hvor
mye.
Forskere som bruker git, kan også klone dette repositoryet og starte Claude Code med `claude --plugin-dir .` i mappa.
Slik sender du en forbedring tilbake: [BIDRA.md](BIDRA.md).
## Status og begrensninger
- Modellen er ikke kalibrert på norske data. Parameterne er stiliserte, og simuleringene illustrerer mekanismer. De
er ikke prognoser.
- Av notatets 39 nummererte ligninger er 18 implementert, 12 forenklet og 9 ikke implementert.
- Bare ett ledd har kø i modellen. Alle simuleringene antar feilfrie observasjoner, og resultatene er enkeltbaner
uten parameterusikkerhet.
- Kostnader og gevinster er ikke regnet i kroner.
- Diagnosen regner på tallene slik de er oppgitt, og kapasitetsbehovet er et grovt anslag.
Alle forbeholdene, for modellen, diagnosen, forløpet og de norske tallene: [docs/forbehold.md](docs/forbehold.md).
## Non-goals
- Ingen prognoser. Kjøringene viser modellens dynamikk.
- Erstatter ikke budsjettarbeidet. Den viser hvor kjeden binder, hvilken type tiltak som følger, og omtrent hvor
stort tiltaket bør være.
- Sier ingenting om enkeltsaker eller enkeltpersoner, og skal bare brukes på aggregerte tall.
- Ingen persondata og ingen data fra enkeltsaker, verken i pluginen eller i det den skal brukes på.
- Kalibrerer ikke modellen mot norske tidsserier.
- Foreslår ikke å endre straffebud eller strafferammer.
## Slik er arbeidet gjort
Arbeidet er et privat eksperiment. Modellen, koden og denne pluginen er i praksis laget av kunstig intelligens
(Claude, Anthropic) etter forfatterens retning. Forfatteren har ikke selv etterprøvd all matematikken, og det kan være
feil og mangler. Forfatteren har ansvaret for innholdet.
Innspill og kritikk er velkomne, særlig fra dem som arbeider i straffesakskjeden og fra forskere som vil prøve
modellen mot data. Send en e-post til hello@fromaitochitta.com.
## Lisens
[MIT](LICENSE).
## Changelog
See [CHANGELOG.md](CHANGELOG.md).

175
skills/forbedre/SKILL.md Normal file
View file

@ -0,0 +1,175 @@
---
name: forbedre
description: "Hjelper den som vil endre eller utvide modellen i notatet Den dynamiske rettsstaten: avklarer om det er andre forutsetninger (et scenario), en ny mekanisme (en utvidelse ved siden av kjernen, med et grensetilfelle som gjenskaper kjernen eksakt) eller en endring i kjernens ligninger; lager en arbeidskopi brukeren eier, finner ligning, funksjon og parameter i modellkartet, og kontrollerer etterpå hvilke av notatets resultater som flytter seg. Sier også hvordan forbedringen sendes tilbake. Bruk når noen vil forbedre, endre, utvide eller kalibrere modellen, legge til en mekanisme, endre en ligning eller sjekke en endring. Utløses av «forbedre modellen», «endre modellen», «legg til en mekanisme», «utvid modellen», «jeg vil endre ligningen for», «lag en arbeidskopi», «sjekk endringen min», «kjør kontrollen», «improve the model», «add a mechanism to the model»."
---
# Forbedre modellen
Ferdigheten hjelper den som vil endre eller utvide modellen i notatet *Den dynamiske rettsstaten*. Endringen gjøres i
en kopi brukeren eier, og en kontroll sier etterpå om notatets resultater står fast, eller hvilke som har flyttet seg
og hvor mye. Den trenger Python 3; kontrollen og kjøringene trenger i tillegg numpy og scipy.
Brukeren er oftest forsker, men ikke nødvendigvis programmerer. Snakk vanlig norsk. Forklar hva du gjør i koden med
ord; vis kode når brukeren vil se den.
## Regler
- **Én endring om gangen.** To endringer samtidig gjør det umulig å si hva som ga hvilket utslag.
- **Hypotesen og grensetilfellet før koden.** Si hva mekanismen skal gjøre, og for hvilken verdi den forsvinner.
- **Hver påstand bygger på en kjøring.** Si aldri at en endring «gir» noe før en kjøring har vist det, og gjengi
skriptets tall ordrett.
- **Kontroll etter hver endring**, og les dommen for brukeren (trinn 6).
- **Modellen er stilisert.** Parameterne er ikke kalibrert på norske data, og kjøringene er ikke prognoser. Det
gjelder også en forbedret modell, til den er kalibrert og prøvd mot data.
- **Installer aldri noe uten å spørre.**
- **Pluginens egen modell endres aldri.** Alt gjøres i kopien.
## 1. Hva vil brukeren endre?
Avklar hvilken av tre ting det er. Spør med vanlige ord, og foreslå svaret når det er opplagt:
| Brukeren vil | Det er | Slik gjøres det |
|---|---|---|
| prøve andre verdier for parameterne, en annen styringsregel, beslutningsregel, sjokk eller tiltak | **et scenario**: ingen kode endres | ferdigheten `simuler` |
| legge til noe modellen ikke har (for eksempel et pådrag som varierer over tid, kø i et ledd til, målestøy) | **en utvidelse**: en ny mekanisme ved siden av kjernen, med et grensetilfelle som gjenskaper kjernen eksakt | trinn 2–7 |
| endre ligningene modellen allerede har (en annen funksjonsform, en annen tilbakekobling) | **en endring i kjernen** | trinn 2–7 |
Mye som ser ut som en endring, er et scenario: alle kjernens parametere kan overstyres i en scenariofil (se
`${CLAUDE_PLUGIN_ROOT}/docs/scenarioformat.md`). Er det et scenario, si det og gå over til ferdigheten `simuler`.
Kan mekanismen stå ved siden av kjernen, anbefal en utvidelse framfor å endre kjernen: notatets resultater ligger da
fast, og grensetilfellet viser at de gjør det.
## 2. Lag en arbeidskopi
Endringer gjøres i en kopi brukeren eier. Si i én setning hvorfor: «Pluginen byttes ut når den oppdateres, så
endringer der ville forsvinne; kopien er din.» Spør før du lager den, og foreslå mappa `rettsstat-modell` i brukerens
arbeidsmappe:
```
python3 "${CLAUDE_PLUGIN_ROOT}/modell/kjor.py" --data "${CLAUDE_PLUGIN_DATA}" arbeidskopi <arbeidsmappe>/rettsstat-modell
```
- På Windows heter tolken `python`. Bruk hele stien.
- Kopien har modellen, eksemplene, fasiten, testene, dokumentasjonen og en `LES-MEG.md`. Den trenger ikke numpy og
scipy for å lages.
- Finnes mappa og er ikke tom, nekter kommandoen (den skriver aldri over noe). Har brukeren en kopi fra før, bruk
den.
- Ferdighetene `diagnose`, `forlop` og `simuler` bruker kopien selv når arbeidsmappa har en `rettsstat-modell/`.
**Forskere som bruker git** kan i stedet klone pluginens repository (`https://git.fromaitochitta.com/open/dynamisk-rettsstat.git`),
endre der og starte Claude Code med pluginen fra klonen: `claude --plugin-dir .` i mappa. Da bruker ferdighetene
klonens modell direkte, og endringene kan sendes tilbake med `git format-patch`. Kontrollen vet ikke at en klone er
en arbeidskopi: ved «endret» sier den at pluginens modell skal regne som notatet, og kaller det en feil. For en
endring som er ment, er det en opplysning; si det til brukeren.
## 3. Finn stedet i modellen
Les `${CLAUDE_PLUGIN_ROOT}/docs/modellkart.md` (kopien har den samme i `docs/`). Den går fra notatets ligninger til
funksjonene og parameterne i `modell/kjerne/sim.py`:
- del (a): tilstanden og ligningene slik koden regner dem;
- del (b): parameterne, verdiene og hvor de står i notatet;
- del (c): ligning → funksjon → status (implementert, forenklet, ikke implementert);
- del (d): de fem simulatorene og hvilke av notatets datafiler og figurer hver gir;
- del (e): grensetilfellene koden selv skriver ut.
Vis brukeren hvilken ligning, funksjon og parameter endringen gjelder, med linjenummer, og hvilken simulator det er
enklest å bygge på.
Merk for endringer i kjernen: `modell/kjerne/diagnose.py` har egne kopier av regelverdiene, og
`modell/kjerne/forlop.py` har en egen kopi av løkka i `simulate_endo` (modellkartet, «Konstanter i `diagnose.py` og
`forlop.py`»). Endres de i `sim.py`, må kopiene endres likt; forløpet stopper ellers med «Intern kontroll feilet».
## 4. Hypotese og grensetilfelle
Skriv ned med brukeren, før noen kode:
- **Hypotesen**: hva mekanismen eller endringen skal gjøre i modellen, og hvorfor (gjerne med henvisning til
litteratur eller data).
- **Grensetilfellet**: verdien av den nye parameteren der mekanismen forsvinner (en faktor lik 1, et ledd lik 0, en
kapasitet lik uendelig). I den verdien skal modellen gi nøyaktig kjernens tall, største avvik `0.0`, ikke bare
lite.
- **Hvilke av notatets resultater** endringen kan tenkes å flytte (for en endring i kjernen), og hvilke den ikke skal
røre.
Få et ja på dette før du skriver kode.
## 5. Gjør endringen
**En utvidelse.** Følg `${CLAUDE_PLUGIN_ROOT}/docs/utvidelser.md`: grensesnittet (`NAVN`, `BESKRIVELSE`,
`PARAMETERE`, `simuler`, `grensetilfelle`, og valgfritt `BRUKER` og `sjekk`), malen mellom `<!-- mal:start -->` og
`<!-- mal:slutt -->` og trinnene der. Kort:
- Fila er `rettsstat-modell/modell/utvidelser/<navn>.py`, og `NAVN` er filnavnet uten `.py`.
- Kopier løkka fra simulatoren du bygger på uendret, og legg mekanismen inn slik at den forsvinner i grensetilfellet.
Bruk kjernens funksjoner der det går, og endre ikke rekkefølgen på regnestegene.
- Standardverdiene i `PARAMETERE` bør være grensetilfellet.
- `grensetilfelle()` kjører utvidelsen i grensetilfellet og kjernen med de samme forutsetningene, og returnerer
største absolutte avvik.
**En endring i kjernen.** Endre `rettsstat-modell/modell/kjerne/sim.py` (og kopiene i `diagnose.py` og `forlop.py`
når det trengs). Endre bare det hypotesen gjelder.
**Skriv en test.** Grensetilfellet i hver utvidelse testes allerede automatisk (`tests/test_utvidelser.py` i kopien).
Skriv i tillegg en test i `tests/` for det mekanismen skal gjøre utenfor grensetilfellet, for eksempel retningen på
utslaget. Testene kjøres med `python3 -m pytest` i kopien og trenger pytest; finnes det ikke, spør før du installerer
det.
## 6. Kontroller
Kjør kontrollen på kopien etter hver endring:
```
python3 "${CLAUDE_PLUGIN_ROOT}/modell/kjor.py" --data "${CLAUDE_PLUGIN_DATA}" --modell <hele stien til rettsstat-modell/modell> kontroll
```
- Den fulle kontrollen kjører hele notatets simulering og tar om lag ett til to minutter. Mens du prøver deg fram,
kan du legge til `--rask` (hopper over den fulle kjøringen); kjør den fulle før du sier hva endringen gjør.
- Kontrollen sammenligner med notatets resultater i `fasit/`: kjernens sjekksummer, utskriften fra diagnosen og
forløpet på begge eksempelfilene, de 22 datafilene og utskriften fra `sim.py`, og grensetilfellet i hver
utvidelse.
Exit-koder: **0** bit for bit eller innenfor toleranse, **1** endret, **2** feil bruk, **3** numpy eller scipy
mangler. Ved 3 er det som kunne kjøres uten dem, kjørt. Spør: «Kontrollen trenger to vanlige regnebiblioteker for
Python, numpy og scipy. Skal jeg installere dem i en egen mappe for denne pluginen?» Bare hvis svaret er ja:
```
python3 "${CLAUDE_PLUGIN_ROOT}/modell/kjor.py" --data "${CLAUDE_PLUGIN_DATA}" miljo --opprett
```
Gjengi det kommandoen sier, og kjør kontrollen på nytt.
**Les dommen for brukeren.** Den står i linja som begynner med «Nivå», nederst:
- **«bit for bit som notatet»**: endringen flytter ingen av notatets resultater. For en utvidelse er det det som skal
skje, og grensetilfellet er eksakt.
- **«innenfor toleranse»**: hvert tall avviker med høyst én enhet i siste viste siffer, som med andre versjoner av
numpy og scipy. Notatets resultater står.
- **«endret: …»**: noe har flyttet seg. Si det rett ut, og si hva:
- hvilke datafiler som er endret, og største absolutte avvik per kolonne (står i detaljene). Bruk modellkartet,
del (d), til å si hvilken figur eller tabell i notatet hver datafil hører til;
- hvilke linjer i diagnosen, forløpet og utskriften fra `sim.py` som er endret (detaljene viser dem som «notatet» og
«nå»), med tallene slik de står;
- om kjernen er endret (punkt 1), og om et grensetilfelle ikke lenger er eksakt (punkt 5).
En endret kjerne er en opplysning, ikke en feil: kontrollen sier det selv i en arbeidskopi. Men det skal sies
tydelig, og **brukeren avgjør om endringen var ment**. Var den ment, gå videre. Flytter en utvidelse notatets
resultater, eller er grensetilfellet ikke `0.0`, er noe galt i utvidelsen: finn feilen før du går videre.
Står det «uten full kjøring, --rask» eller «bare det som er kjørt» i nivålinja, gjelder dommen bare en del av
kontrollen. Si det, og si ikke at endringen er kontrollert før den fulle kontrollen er kjørt.
Gjengi tallene fra kontrollen slik de står. Regn ikke ut egne avvik.
## 7. Prøv endringen
Kjør et scenario med kopien for å se hva endringen gjør, med ferdigheten `simuler` (den bruker kopien med
`--modell`). For en utvidelse er `"modell": "utvidelse:<navn>"` og parameterne under `"utvidelse"`; et sveip over
utvidelsens parameter, med grensetilfellet som én av verdiene, viser utslaget mot kjernen i samme tabell.
Si hva kjøringen viser, med skriptets tall, og ta med forbeholdet: parameterne er notatets stiliserte verdier, og
kjøringene viser modellens dynamikk, ikke prognoser. Neste endring kommer først når denne er kontrollert.
## 8. Send forbedringen tilbake
Vil brukeren dele forbedringen, står framgangsmåten i `${CLAUDE_PLUGIN_ROOT}/BIDRA.md`. Kort: en e-post til
hello@fromaitochitta.com med endringen (en patch eller de endrede filene), utskriften fra kontrollen og
scenariofilene som viser virkningen. Én mekanisme eller endring om gangen, med grensetilfelle og test, og ingen
persondata eller data fra enkeltsaker. Det er et privat prosjekt, og det er ikke lovet noe svar innen en bestemt tid.

180
skills/simuler/SKILL.md Normal file
View file

@ -0,0 +1,180 @@
---
name: simuler
description: "Kjører modellens simuleringer i notatet Den dynamiske rettsstaten med egne forutsetninger: fra et spørsmål («hva om …») til en scenariofil, en kjøring, en tabell med nøkkeltall og tilbud om figur. Dekker styringen (forsinkelse, reaktivitet, MPC), parameterne, beslutningsreglene for påtale og budsjett, sjokk, tiltak (andel ledet utenom, mer kapasitet i domstolen) og sveip over én eller to parametere, og gjenskaper notatets figurer. Bruk når noen vil prøve modellen med andre forutsetninger, sammenligne regler eller tiltak, se hvor grensen for svingninger går, eller lage notatets figurer på nytt. Utløses av «hva om forsinkelsen er seks måneder», «kjør et scenario», «simuler», «sammenlign reglene», «sveip over», «hva skjer med et større sjokk», «lag figuren i notatet på nytt», «run a scenario», «simulate the model with other assumptions»."
---
# Kjør modellen med egne forutsetninger
Ferdigheten går fra et spørsmål om modellen til en kjøring: hva om forsinkelsen er lengre, sjokket større, kapasiteten
kommer tidligere eller beslutningsreglene er andre? Den skriver spørsmålet som en scenariofil, kjører modellens
simuleringer i notatet *Den dynamiske rettsstaten* (avsnitt 8) med kjernens kode uendret, og viser nøkkeltallene.
Den trenger Python 3 med numpy og scipy.
Brukeren kan være forsker eller arbeide i straffesakskjeden. Snakk vanlig norsk. Nevn ikke filnavn, kommandoer,
feltnavn eller JSON med mindre brukeren spør etter dem, eller viser at de kjenner dem.
## Regler
- **Finn aldri på et tall.** Forutsetningene er brukerens eller notatets. Alt scenariofila ikke setter, er notatets
verdier; si hvilke som er brukt når det betyr noe for svaret.
- **Vis scenarioet med ord, og få et ja før du kjører.**
- **Gjengi skriptets tall ordrett.** Regn aldri om, avrund aldri annerledes og «forbedre» aldri et tall. Vil brukeren
vite hva som skjer med andre forutsetninger, endrer du scenarioet og kjører på nytt.
- **Si hver gang** at parameterne er notatets stiliserte verdier, ikke kalibrert på norske data, og at kjøringene
viser modellens dynamikk, ikke prognoser.
- **Installer aldri noe uten å spørre.** Det gjelder også et bibliotek for figurer.
## 1. Finn ut hva som skal sammenlignes
Spør hva brukeren vil vite, med vanlige ord: hva skal endres, hva skal det sammenlignes med, og hva vil brukeren se
på (kriminalitet, tillit, saksbehandlingstid, kø, kapasitet, andel ledet utenom, politiets innsats)? Ett spørsmål om
gangen.
Oversett så spørsmålet til modellen. Les `${CLAUDE_PLUGIN_ROOT}/docs/scenarioformat.md` før du skriver en scenariofil
første gang: den sier hvilken simulator som dekker hva, hvilke felt og parametere som finnes, hva som er tillatt, og
hvordan sveip virker. For hva en parameter betyr, hvilken ligning den står i og notatets verdi, les
`${CLAUDE_PLUGIN_ROOT}/docs/modellkart.md`. Gjengi ikke dokumentene for brukeren; bruk dem til å velge.
Et sveip er ofte det brukeren egentlig spør om: «hva om forsinkelsen er 3, 6 eller 11 måneder» er én kjøring med tre
verdier, side om side. To parametere gir et rutenett.
**Utgangspunkter som følger med.** Tilby dem når de passer, og si hva de er. De ligger i
`${CLAUDE_PLUGIN_ROOT}/eksempler/scenarioer/`:
| Fil | Spørsmål |
|---|---|
| `avviklingstid_koordinert.json` | hvor raskt bør restansen avvikles i den koordinerte regelen (fra 6 til 96 måneder og aldri)? |
| `stabilitet_reaktivitet_forsinkelse.json` | hvor går grensen for svingninger, over reaktivitet og forsinkelse? |
| `sjokkstorrelse_kjede.json` | hvor mye betyr størrelsen på sjokket når domstolen er en flaskehals? |
| `kvalitetssloyfe.json` | hva gjør kvalitetssløyfen med desentraliserte og koordinerte regler? |
| `utvidelse_bolge.json` | hva etterlater en forbigående bølge i kriminalitetspresset, med og uten flaskehals? |
I undermappa `notatet/` ligger 21 scenariofiler som til sammen lager 20 av notatets 22 datafiler på nytt, det
figurene i notatet tegnes fra (regimene i figur 4, scenario 1–5 med domstolen, robusthet, vippepunkt og de endogene
reglene; de to siste datafilene er regnet analytisk, ikke simulert). Med dem kan brukeren se nøyaktig hvilke
forutsetninger en figur i notatet bygger på, og endre én av dem. Tabellen i `docs/scenarioformat.md`
(«Eksempelfilene») sier hvilken fil som gir hvilken av notatets datafiler.
Eksemplene kjøres direkte fra pluginen. Skal et eksempel endres, kopierer du det til brukerens arbeidsmappe først og
gir kopien et nytt navn.
## 2. Vis scenarioet og få et ja
Beskriv scenarioet med ord før du kjører:
- **Hva som varieres**, med verdiene (for eksempel «forsinkelsen i politiets styring: 3, 6 og 11 måneder»).
- **Hva som holdes fast**: modellen (for eksempel «domstolen som ledd med kø, avsnitt 8.2»), og hva som er notatets
verdier (styring, sjokk, parametere, regel).
- **Over hvor mange måneder**, og hvor mange kjøringer det blir.
Spør: «Skal jeg kjøre dette?» Kjør ikke før brukeren har sagt ja.
## 3. Skriv scenariofila
Skriv scenarioet som en JSON-fil i brukerens arbeidsmappe, med et kort `navn` uten mellomrom og en `beskrivelse` som
sier spørsmålet med vanlige ord (den står øverst i sammendraget). Feltnavnene skrives nøyaktig som i
`docs/scenarioformat.md`. Finnes fila fra før, spør før du overskriver den. Gi en ny variant et nytt `navn`, så
resultatet fra forrige kjøring blir stående.
## 4. Kjør
```
python3 "${CLAUDE_PLUGIN_ROOT}/modell/kjor.py" --data "${CLAUDE_PLUGIN_DATA}" scenario <fil> --ut <mappe>
```
- På Windows heter tolken `python`.
- `<fil>` er hele stien til scenariofila. `<mappe>` er `resultater/<navn>` i brukerens arbeidsmappe, med hele stien.
Finnes mappa med et tidligere resultat av samme scenario, erstattes det. Finnes den med andre filer, stopper
kjøreren uten å skrive noe.
- Har brukerens arbeidsmappe en egen arbeidskopi av modellen (mappa `rettsstat-modell/` med `modell/kjor.py` inni),
legger du til `--modell <hele stien til rettsstat-modell/modell>` før `scenario`, og sier til brukeren: «Jeg bruker
din egen versjon av modellen i rettsstat-modell.» Bruk ellers pluginens modell.
- Et scenario med noen få kjøringer tar noen sekunder. MPC er tregt (om lag 7 sekunder per kjøring), og et rutenett
med mange kjøringer tar tilsvarende lenger.
Exit-koder:
- **0**: kjøringen er gjort. Gå til trinn 5.
- **3**: numpy eller scipy mangler. Si i én setning: «Simuleringene trenger to vanlige regnebiblioteker for Python,
numpy og scipy. Skal jeg installere dem i en egen mappe for denne pluginen?» Installer bare hvis svaret er ja:
```
python3 "${CLAUDE_PLUGIN_ROOT}/modell/kjor.py" --data "${CLAUDE_PLUGIN_DATA}" miljo --opprett
```
Gjengi det kommandoen sier (blant annet om resultatene da kontrolleres bit for bit eller med toleranse), og kjør på
nytt. Feiler installasjonen, gjengi meldingen og si at diagnosen fortsatt kan brukes uten tilleggene.
- **2**: skriptet har stoppet med en melding. Les den:
- *Feil i scenariofila …*: meldingen nevner feltet og de gyldige verdiene, og foreslår det nærmeste ved en
skrivefeil. Gjengi den med vanlige ord, rett fila, vis endringen og kjør på nytt. Er det brukerens forutsetning
som ikke er tillatt (for eksempel en andel over 1), spør hva som var ment.
- *… er ikke gyldig JSON*: rett fila og kjør på nytt.
- *Kjøringen … stoppet i kjernen*: kombinasjonen av forutsetninger gir ingen likevekt ved start eller en løsning
som vokser over alle grenser. Si det med vanlige ord, og hvilken kjøring det gjaldt. Ingenting er skrevet. Endre
aldri en forutsetning bare for at kjøringen skal gå; spør brukeren.
- *--ut: mappa … finnes og har filer …*: velg en annen mappe og si hvilken.
- *Uventet feil i …*: en feil i koden, ikke i scenarioet. Gjengi meldingen og si at kjøringen ikke ble gjort.
- **Annen kode, eller `python3` finnes ikke**: gjengi meldingen og si at kjøringen ikke ble gjort. Gjett ikke på et
svar.
## 5. Presenter svaret
1. **Vis nøkkeltallene slik skriptet skrev dem.** Kjøreren skriver sammendraget til skjermen og til `sammendrag.md`.
Vis tabellen (eller tabellene) under «Nøkkeltall» uendret, med linja «Slik leses tallene» under, og for
beslutningsreglene budsjettvedtakene. Ikke avrund, regn om eller formater tallene på nytt, og ta ikke bort rader.
Er tabellen svært stor, vis radene brukeren spurte om, og si hvor resten står.
2. **Les den med vanlige ord**, kort: hva endringen gjør i modellen, i hvilken retning og hvor mye, med skriptets
tall. Pek på det som er verdt å se: høyeste mot slutt (har forløpet funnet en ny balanse?), vedvarende svingning
(spennet de siste 60 månedene), saksbehandlingstid og tillit, og kapasitet og andel ledet utenom der de endres.
Si ikke mer enn tallene viser.
3. **Forbehold** som alltid tas med:
- Parameterne er notatets stiliserte verdier (tabell 3 i notatet), ikke kalibrert på norske data, unntatt det
scenarioet setter selv. Kjøringene viser modellens dynamikk, ikke prognoser. Rekkefølgen og retningen er
poenget, ikke nivåene.
- Kø, strøm og kapasitet er i modellens normaliserte enheter, ikke saker eller årsverk. 1,00 er nivået før
sjokket.
- Bare ett ledd har kø i modellen (domstolen); politi, påtale og kriminalomsorg har ikke kø.
Ta i tillegg med det som gjelder dette scenarioet, fra `${CLAUDE_PLUGIN_ROOT}/docs/forbehold.md` (for eksempel at
beslutningsreglene er stiliserte, eller at andelen som kan ledes utenom er et rettspolitisk valg).
4. **Si hvor filene ligger**: sammendraget, én CSV-fil per kjøring (én rad per måned) og `resultat.json` med alle
parametere slik de ble brukt, versjonene og sjekksummene. Samme scenariofil gir samme filer, så kjøringen kan
etterprøves.
## 6. Tilby en figur
Spør: «Vil du se dette som en figur?» Lag den bare hvis svaret er ja.
- **Bruk tallene kjøringen skrev**, uendret: CSV-filene i resultatmappa (med `"format": "notat"` er det `.dat`-filer,
med mellomrom mellom feltene). Regn ikke ut nye størrelser for figuren, og glatt ikke kurvene.
- **Lag figuren slik miljøet tillater** uten å installere noe: med et plottebibliotek som allerede finnes, eller som
en tegning du lager selv (for eksempel SVG eller en HTML-side). Mangler alt, spør før du installerer noe.
- **Én kurve per kjøring**, med kjøringens navn fra sammendraget i forklaringen (for eksempel «forsinkelse=6»).
- **Aksene på norsk**: «Tid (måneder)» og størrelsen, for eksempel «Kriminalitet K», «Tillit», «Politiets innsats
T», «Saksbehandlingstid i domstolen (måneder)», «Kapasitet (1,00 = ved start)» eller «Andel til domstolen». Hva
kolonnene betyr, står i `docs/scenarioformat.md` («Tidsseriene per modell»).
- **Ta med linja om hva 1,00 betyr** under figuren, som i sammendraget: «1,00 er nivået i referanselikevekten før
sjokket for kriminaliteten K og politiets innsats T; tilliten er 0,80 der. Kapasitet: 1,00 er kapasiteten ved
start.» Skriv i tillegg at tallene er modellens stiliserte dynamikk, ikke prognoser.
- Lagre figuren i resultatmappa og si hvor den ligger.
## Hva scenariokjøreren ikke gjør
Si det rett ut når spørsmålet ligger utenfor:
- **Egne tall i saker per måned** (innstrømning, kapasitet og restanse per ledd) hører hjemme i ferdighetene
`diagnose` (leddet som binder) og `forlop` (forløpet måned for måned med tallene dine). Scenariokjøreren bruker
modellens normaliserte størrelser.
- **En mekanisme modellen ikke har** (for eksempel kø i flere ledd, målestøy, forskyvning mellom kategorier) kan
ikke settes inn med en parameter. Den legges til som en utvidelse; det er ferdigheten `forbedre`.
- **Endrer scenarioet** `P.gamma`, `P.Lam0` eller `P.T0`, regnes domstolens kapasitet og behandlingstid ikke om, og
domstolen er da ikke lenger 95 % utnyttet før sjokket. Si det, og oppgi dem selv hvis brukeren vil ha det (se
`docs/scenarioformat.md`).
- Ingen kjøring kalibrerer modellen mot norske tidsserier eller lager prognoser.
## 7. Neste steg
Tilby det som passer:
- en variant med én forutsetning endret, kjørt med nytt navn og vist ved siden av den første, med skriptets tall;
- et sveip over forutsetningen brukeren er mest usikker på;
- notatets scenariofil for samme figur, for å se forskjellen mot notatets forutsetninger;
- ferdigheten `forbedre`, hvis spørsmålet krever en mekanisme modellen ikke har.