jobbsok/docs/2026-09-04-kvalitetsrevisjon-planlegging.md
Kjell Tore Guttormsen 2076f617e0 docs(plan): revisjon etter kvalitetsrevisjonen 04.09
Operatoerbeslutning (b): revider planen foer M1. Ordre
20260904T135502Z-687411640-from-.claude, ti punkter, alle utfoert i
plan.md og brief.md under .claude/projects/ (local-only, gitignored) --
denne seksjonen i revisjonsrapporten er den sporede baereren.

Gater ved levering, kjoert 2026-09-04:
- plan-validator.mjs --strict: valid, 56 steg, 0 errors/warnings
- brief-validator.mjs: valid, 0 errors/warnings
- oekt 2s gate-script (33 grep-kriterier): PASS=33 FAIL=0
- grep -c 'Pass 2' plan.md: 6
- de tolv "Foreldet tekst"-greppene: PASS=12 FAIL=0

Ingen kode skrevet, ingen M1-steg utfoert. 56 steg inn, 56 steg ut.

Tre avvik fra ordreteksten, begrunnet i rapporten: --check i 5 av 6
Cowork-steg (steg 16 er M1, sak_status.py finnes foerst i steg 17);
det tolvte scriptet i avviksnoten er jobbsok_tools.py, ikke
kandidat_schema.py (som allerede sto der); Pass 2-seksjonen staar sist
i fila, der trekplan.md anviser, med peker fra planhodet.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 17:07:11 +02:00

435 lines
29 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.

# Kvalitetsrevisjon av planleggingen (2026-09-04)
Måling, ikke bygging. Ordre fra PM 2026-09-04: hvorfor rapporterer jobbsok selv
lav kvalitet, og holder `plan.md` mot `docs/build-brief.md`. Ingen fil i planen
er endret. M1 er ikke startet.
Kilder (alle lokale): `docs/build-brief.md` (417 linjer), Voyage-prosjektet
`.claude/projects/2026-09-03-jobbsok-plugin-build/` (brief.md 316 linjer,
research/01-03, exploration/, plan.md 2223 linjer / 56 steg), `STATE.md`, og de to
planleggingsøktenes transkripter med underagent-transkripter (økt 1 Fable 5.1,
økt 2 Opus 5). Kommandodefinisjonene er lest i voyage 5.10.1 (`commands/trekbrief.md`,
`commands/trekplan.md`, `lib/review/plan-review-dedup.mjs`, `lib/validators/`).
## Anbefaling
**(b) Revider planen først** — steg 1 (probens forutsetninger: navngi test-pluginen og
at operatøren må sitte i Cowork), 13 (`.gitignore`-linjen for `BUILD_STAMP` må testes),
20 (motsier `--oppdater`), 21 (`--oppdater`-kallet er utestet), 23 (`dagens`-ekkoet
mangler), 26 (benign-korpus og tak-brøk er udefinerte), 31 (proben har ingen Verify og
skriver utenfor sesjon 8s gjerde), alle seks `Verifiser i Cowork`-steg (`--check`
kjøres i ett av seks), planhodet (Pass 2-markøren mangler, graden B er egenvurdert),
sesjonsgjerdene 4 og 8, og `brief.md` linje 193–194 og 245 (`zip -r`, «version-echo
skill», `plugin.json`-versjon) — deretter GO på M1 sesjon 1; ikke (c), fordi
`docs/build-brief.md` ikke er gyldig `/trekplan`-input og research 02/03 endret to
designbeslutninger som en omplanlegging ville mistet.
Bakgrunnen for operatørens observasjon: den lave kvaliteten som ble rapportert, var
reell for planen *før* revisjon (plan-critic: REPLAN, 65.8/100) og rapportene var
ærlige om det. Planen *etter* revisjon har ingen anmelder-verdict; graden B/84 i
planhodet er øktens egen. Fire av ni blockers er lukket bare delvis i stegteksten.
## Sammendrag i fire tall
| # | Måling | Resultat | Nevner |
|---|--------|----------|--------|
| 1 | Steg uten anker i `docs/build-brief.md` | 0 (41 direkte, 15 avledet via beslutning/research/risiko) | 56 steg |
| 2 | Blockers faktisk lukket i stegtekst | 5 lukket, 4 delvis, 0 bare notert | 9 blocker-rader i `## Revisions` |
| 3 | Kontekst ved økt 1s siste melding | 491 688 tokens | vindu ikke registrert i transkriptet |
| 4 | Probens fire spørsmål avgjørbare fra Claude Code | 0 | 4 |
## 1. Sporbarhet: 56 steg mot briefens paragrafer
Klassifisering per stegs primære leveranse (`Files:`-linjen), strengt:
DIREKTE = paragrafens egen tekst ber om leveransen; AVLEDET = ingen paragraf ber om
leveransen selv, den tjener et briefkrav via en operatørbeslutning (1–7 i brief.md),
en research-fil eller en risiko-ID; INGEN = ingen av delene.
| Klasse | Steg | Antall |
|--------|------|--------|
| DIREKTE | 2–9, 11, 14, 15, 17–23, 26–29, 31, 34–36, 38–40, 43–46, 48–55 | 41 / 56 |
| AVLEDET | 1, 10, 12, 13, 16, 24, 25, 30, 32, 33, 37, 41, 42, 47, 56 | 15 / 56 |
| INGEN | — | 0 / 56 |
De 15 avledede fordeler seg på fire kilder:
| Kilde | Steg | Hva briefen sier |
|-------|------|------------------|
| Cowork-akseptanse per milepæl (brief.md Preferences) | 1, 16, 25, 37, 42, 47, 56 | §3 navngir Cowork som operatørflate; ingen paragraf ber om verifisering per milepæl |
| Beslutning 7 (host-side MCP-server) + research 03 | 12, 24 | §8 deklarerer nøyaktig to servere; den tredje er beslutningen |
| Risiko-ID alene | 10 (H5, scoring-aritmetikk i script), 13 (H11, byggestempel), 30 (C4, norsk leksikon-gap), 33 (M15r/H15, tools/list-golden) | ingen paragraf nevner disse |
| Beslutning 6 / research 02 | 32 (hook: §8 ber om «read tools only», research 02 målte at ingen slik opsjon finnes) | §2.1 er kravet hooken tjener |
| Beslutning 2 | 41 (asserter at mail-serveren er fraværende) | §8.2 krever en mail-server; fraværstesten finnes bare fordi den er utsatt |
`Source:`-linjen i stegene siterer `docs/build-brief.md` i 29 av 56 steg; 27 siterer
bare research, risiko, beslutning eller test-strategist. Steg 26–28 bygger §9s
sikkerhetsgrense, men `Source:` nevner bare research 01 og risiko-IDer; §9 står i
`Changes:`-prosaen. Operatørkjørte steg uten automatisk test: 7 av 56 (steg 1 og de
seks Cowork-stegene).
Full tabell med sitat per steg ligger i revisjonens arbeidsfil (ikke sporet);
tabellen over er summen av den.
### Scripts-avviket
Briefens §4 navngir tre scripts (`guard_ingest.py`, `sak_status.py`, `dashboard.py`).
Briefens §6 er den eneste setningen som begrunner et script med reproduserbarhet,
og den gjelder `sak_status.py` alene. Planen skriver tolv til.
Målt: `grep -o 'scripts/[A-Za-z0-9_./-]*' plan.md | sort -u` → 23 filer under
`scripts/`. 3 er i §4. 20 er «ikke i brief» som fil: 12 kapabilitets-scripts, 4 filer
i `jobbsok_lib/`, 4 shell-hjelpere. Planens egen avviksnote teller elleve
kapabilitets-scripts; den tolvte, `kandidat_schema.py` (steg 8), står ikke i listen.
| Script | Steg | I brief? | Briefparagraf det tjener | Nærmeste begrunnelse |
|--------|------|----------|--------------------------|----------------------|
| `kandidat_schema.py` | 8 | ikke i brief | §5.1 (valider, ikke regenerer) | risiko H7 (ingen YAML-avhengighet) |
| `vurdering.py` | 10 | ikke i brief | §7 `kandidatvurdering` | risiko H5 (`score_da` må ikke være modell-output), beslutning 3 |
| `jobbsok_tools.py` | 12, 24 | ikke i brief | — (§8 sier to servere) | beslutning 7, research 03 |
| `jobbsok_tools_launch.sh` | 12 | ikke i brief | — | beslutning 7, risiko H2 |
| `build_stamp.sh` | 13 | ikke i brief | — | risiko H11 |
| `package_plugin.sh` | 13 | ikke i brief | — | Cowork-akseptanse, blocker 9 |
| `bootstrap.sh` | 2 | ikke i brief | §9 (pin, ikke vendor) | risiko H2 |
| `beslutninger.py` | 22 | ikke i brief | §5.4 | risiko H4 |
| `dagens.py` | 23, 41 | ikke i brief | §11 M2 («dagens as text output») | risiko H9 |
| `korrespondanse.py` | 38, 39 | ikke i brief | §7 `korrespondanse`, §8.2 | beslutning 2 |
| `soknad.py` | 43 | ikke i brief | §7 `soknad` («Versioned, never sent») | risiko L4 |
| `referanser.py` | 45 | ikke i brief | §5.6 | risiko M13r |
| `cv_varianter.py` | 46 | ikke i brief | §5.5 | risiko M11r |
| `utfall.py` | 48 | ikke i brief | §5.7 | risiko H4 |
| `laering_signal.py` | 49 | ikke i brief | §7.2 | risiko H6 |
| `datahygiene.py` | 54 | ikke i brief | §7 `datahygiene`, §14.4 | beslutning 4, risiko M12r |
| `jobbsok_lib/{__init__,paths,frontmatter,jsonl}.py` | 3, 4, 5 | ikke i brief | §5, §5.1, §2.6 | risiko C6, H7, H4, H8 |
Hvert script tjener en paragraf; ingen paragraf ber om scriptet. Avviket er
dokumentert i planen og venter på operatørens ja (Revisions rad 7). Det er ett
spørsmål, ikke tolv: «skal deterministisk logikk ligge i scripts også der briefen
ikke sier det». Alternativet nevnt i `STATE.md` (slå loggskriverne sammen til én
modul) reduserer antallet filer, ikke antallet steder logikk må testes.
## 2. Review-funnene i fase 9
### Tallene stemmer ikke overens, og hvert tall har en egen tellemåte
| Kilde | Blockers | Majors | Minors | Sum | Tellemåte |
|-------|----------|--------|--------|-----|-----------|
| plan-critic, egen oppsummering (transkript) | 7 | 14 | 15 | 36 | agentens prosa: «Blockers: 7 / Major: 14 / Minor: 15», score 65.8/100, grad C, **verdict REPLAN** |
| plan-critic, unike JSON-funn | 7 | 13 | 15 | 35 | unike `(line, rule_key)` i agentens JSON-blokker, som kom i fire avkuttede deler |
| scope-guardian, unike JSON-funn | 0 | 6 | 5 | 11 | samme metode; verdict MIXED, «no blockers» |
| coord-melding fra økt 2 til PM | 7 | 14 | 20 | 41 (+12 guardian) | tallene økt 2 rapporterte videre; 20 minors finnes ikke i noen kilde |
| `STATE.md` | 7 | 12 | 14 | 33 | «33 funn innarbeidet» |
| `plan.md ## Revisions` | 9 | 19 | 5 | 33 | severity-kolonnen, talt med `awk` over 33 rader; rad 33 er en klynge på ti småfeil |
Kommando for den siste raden:
```bash
sed -n 2169,2223p plan.md | grep -E '^\| [0-9]+ \|' | awk -F'|' '{print $4}' | sort | uniq -c
```
Ordrens premiss «7 blockers / 14 majors / 20 minors» er altså plan-critics egne
tall for blockers og majors, med et minor-tall som ikke gjenfinnes. Revisjonstabellen
graderte to funn opp til blocker (rad 1, review-køen var skrivebeskyttet, som
guardian ga major; rad 16, hooks.json-scope, som er den andre halvdelen av critics
blocker på linje 1115).
### Er blockerne lukket i planteksten?
Regel: LUKKET = hvert element i Resolution-cellen står i stegteksten *og* dekkes av
en navngitt test eller stegets Verify-kommando; DELVIS = et element står bare i
tabellen, eller i `Changes:` uten test; BARE NOTERT = bare i tabellen.
| Rad | Blocker | Verdict | Belegg (plan.md-linje) | Det som mangler |
|-----|---------|---------|------------------------|-----------------|
| 1 | Review-køen var skrivebeskyttet | LUKKET | 1006 (leser `--review list/show/godkjenn/avvis`), 1012 (test), 1196/1202 (annonse-uttrekk møter køen) | — |
| 8 | `BUILD_STAMP` mot flyttende HEAD | DELVIS | 515 (byggeartefakt), 519/525 (test på ferskt stempel), 527 | «gitignored» står i 515, men `.gitignore` er verken i `expected_paths` (533–536), `must_contain` (544–546) eller testen (525) |
| 9 | `zip -r` lekker `.git`/venv/STATE/`.claude` | LUKKET | 514/517 (include-liste), 519/525 (arkivets innholdsfortegnelse testes), 607, 2005 | — |
| 10 | PreToolUse-hook feilet åpent | LUKKET | 1132 (begge navneformer, normalisering, scoped matcher), 1138 (test viser at bar-navn-sammenligning feiler åpent), 1157–1160 | — |
| 11 | `karantene/`, `.review/`, `kandidater/` uten scaffold og sletting | LUKKET | 186 (scaffold), 192, 1821 (steg 54 feier alle tre), 1827 (skanner hele workspace) | — |
| 13 | Disposisjonsautoritet udefinert | LUKKET | 939 («`decide` is authoritative»), 946 (test: wrapperen beregner ingen disposisjon), 948 | — |
| 14 | Falsk-positiv-raten aldri nevnt | DELVIS | 940 (lenker pakkes ut, review bemannet), 946 (`active:raw-html` fortsatt fanget) | tak-testen i 946/948 måler «a stated fraction» over «the benign corpus»; brøken er aldri oppgitt, og intet steg lager et benign-korpus for guarden (eneste benigne fixture er én fil, `adv-07-benign.json`, laget i steg 29, *etter* steg 26) |
| 15 | `sak.md`-frontmatter aldri skrevet tilbake | DELVIS | 653 (`--oppdater` eier fire nøkler), 659 (test: `--check` feiler uten), 778 (skillen kjører den) | «every Cowork step now runs `--check`» er usant: `grep -n -e '--check' plan.md` gir 7 linjer, den eneste i et Cowork-steg er 912 (steg 25); 1 av 6. Skillens `--oppdater`-kall (778) har ingen test (784) og ingen `must_contain` (803–805). Steg 20 (747/753) kaller scriptet «a reader … writes nothing» uten forbehold |
| 16 | hooks.json-scope uspesifisert; Cowork-hook umålt | DELVIS | 1132/1138 (scope), 1986–1987 (antakelse 7 og 8) | proben i steg 31 (1103) har ingen Verify (1108 tester bare `.mcp.json`), `docs/cowork-probe.md` er ikke i `expected_paths` (1114–1116) og ikke i sesjon 8s gjerde (2086) |
Fem av ni lukket, fire delvis, ingen bare notert. Ingen av de fire delvise gjelder M1
sesjon 1 (steg 1–3).
Foreldet tekst som fortsatt motsier en lukket blocker, funnet med grep:
| Sted | Tekst | Motsier |
|------|-------|---------|
| `brief.md:193` | «package `zip -r jobbsok.plugin .`» | blocker 9 |
| `brief.md:194` | «run the version-echo skill» | funn 2 (ekkoet bor i `kandidatprofil`, ingen femtende skill) |
| `brief.md:245` | «the version-echo skill prints the `plugin.json` version» | blocker 8 (steg 13, linje 515: «that stamp, not `plugin.json`'s version») |
| `plan.md:103` | Research Sources: «installs are UI-only (`zip -r jobbsok.plugin .` …)» | blocker 9 |
| `plan.md:384` vs steg 23 (842–872) | «From M2 the same echo is also available from `dagens`»; steg 23 nevner verken ekko eller stempel (0 treff) | funn 2s egen løsning |
| `plan.md:747/753` | steg 20: «The script writes nothing: it is a reader» | blocker 15 (`--oppdater`) |
| `plan.md:2054` | sesjon 4s gjerde mangler `package_plugin.sh`, `tests/test_plugin_manifest.py` og `.gitignore` (steg 13s filer) | blocker 8 og 9 |
| `plan.md:2086` | sesjon 8s gjerde mangler `docs/cowork-probe.md` (steg 31s probe) | blocker 16 |
Sjekket og *ikke* funnet: `.review` skrevet uten leser (hver skriving har en leser:
1006, 1196, 1821); Cowork-steg som fortsatt pakker repo-roten (ingen; alle seks
sier `package_plugin.sh`); `BUILD_STAMP` omtalt som sporet fil (ingen); hook som
sammenligner bare navn som design (ingen).
### Dedup-helperen: 21 inn, 21 ut
Helperen (`lib/review/plan-review-dedup.mjs`) slår sammen på to måter, lest i kilden:
eksakt `file:line:rule_key`, ellers Jaccard ≥ 0.7 på ordmengdene i `text`.
Inndataene (rekonstruert fra økt 2s transkript) var 9 critic-funn (7 blockers + 2
majors) og 12 guardian-funn. Lest par for par er **2 av 21** reelle duplikater:
linje 509 (versjons-ekko) og linje 1909 (den andre nettverkstesten). Målt med
helperens egen `tokenize` og `jaccardSimilarity`:
| Par | rule_key critic | rule_key guardian | Jaccard | Terskel |
|-----|-----------------|-------------------|---------|---------|
| linje 509 | `risk-premortem/h11-stamp-unavailable-when-degraded` | `gap` | 0.236 | 0.7 |
| linje 1909 | `coverage-completeness/second-network-test-missing` | `gap` | 0.404 | 0.7 |
Begge feiler begge kriteriene. Den falske negativen er reell og reproduserbar.
Over hele mengden unike funn (35 critic + 11 guardian = 46) er det 7 duplikatpar
lest for hånd: linje 509, 1909, 1745 (dagens kaller ikke dashboard.py), 1991
(Estimated Scope vs manifester), 1992 (script-tellingen), 183/281 (workspace-scaffold)
og 1055/1080 (fixture-nummerering). De fem siste nådde aldri helperen fordi
critics minors ennå ikke var transkribert da den ble kjørt. Netto unike defekter: 39.
### Det ingen anmelder har sett
- Planens hode sier «Plan quality: B (84/100), APPROVE_WITH_NOTES after Phase 9».
Det er øktens egen omskåring. Den eneste anmelder-verdicten på planen er
plan-critics **REPLAN, 65.8/100** på pre-revisjonsversjonen. Ingen anmelder har
vurdert den reviderte planen. Kommandodefinisjonen sier selv at en ny
critic-runde «carries the same loop risk it always did»; det er en kjent avveining,
men da må planens grad merkes som egenvurdert.
- Høy-effort-planer skal ifølge `commands/trekplan.md` bære seksjonen
`## Adversarial Pass 2 (v5.1.1 high-effort)` med status «unavailable, skipped»,
«Do NOT fail, retry, or silently omit the section». `grep -n 'Pass 2' plan.md`
gir 0 treff. Planens hode nevner utelatelsen i prosa, men markøren mangler.
Valideringen som *er* kjørt, holder ved re-måling 2026-09-04:
`plan-validator.mjs --strict` → valid, 56 steg; økt 2s gate-script → PASS=33 FAIL=0.
## 3. Prosessen
### Økt 1 (Fable 5.1), målt fra transkriptet
Kostnad og modellbruk (transkriptets `cost-state`):
| Modell | Input | Output | Cache-skriving | Cache-lesing | Kostnad |
|--------|-------|--------|----------------|--------------|---------|
| Fable 5.1 (hovedkontekst) | 6 263 | 120 802 | 467 617 | 18 734 033 | 20.14 USD |
| Opus 5 (16 underagenter) | 330 131 | 315 287 | 1 196 493 | 17 514 584 | 25.77 USD |
| Haiku 4.5 (64 websøk-kall) | 1 739 996 | 77 530 | 0 | 0 | 2.77 USD |
| Sum | | | | | 48.67 USD, 59.6 min veggklokke, 117 min API-tid |
Ingen `Agent`-spawn i økten valgte Haiku (alle 16 underagent-transkripter viser
`claude-opus-5`). Haiku-tokenene bærer de 64 websøk-forespørslene; hva verktøyet
bruker modellen til, er ikke målbart fra transkriptet.
Hovedkontekstens vekst per fase (nye tokens = `cache_creation + input`, én telling
per meldings-id):
| Fase | Meldinger | Nye tokens i kontekst | Output | Kontekst ved fasens slutt | Underagenter |
|------|-----------|-----------------------|--------|---------------------------|--------------|
| 0 oppsett + repo-init | 9 | 88 629 | 7 237 | 113 711 | 0 |
| 1 trekbrief --quick | 19 | 70 230 | 29 862 | 182 907 | 3 brief-reviewer |
| 2 trekresearch x3 | 25 | 206 449 | 47 207 | 387 895 | 10 (4 lokale, 6 eksterne) |
| 3 trekplan fase 1-5 | 3 | 31 286 | 8 209 | 419 022 | 3 (brief-reviewer, risk-assessor, test-strategist) |
| 4 avslutning (retur, STATE, lagring) | 13 | 73 368 | 28 173 | 491 688 | 0 |
Research-fasen alene la 206 449 tokens i hovedkonteksten, det meste ved at ti
agentrapporter ble lest inn og triangulert der. Økt 1 returnerte ordren med
begrunnelsen «40 pct context»; PM-ordren sier «60 pct». Ingen av prosentene kan
måles: transkriptet registrerer ikke kontekstvinduet. Det absolutte tallet er
491 688 tokens ved siste melding.
Økt 2 (Opus 5) til sammenligning: 38.05 USD, 69 min API-tid, planen på 2 149 linjer
skrevet som seks `Bash`-heredocs mellom 19:34 og 19:43 pluss halesegmentene 19:46,
deretter fase 9 til 20:18.
Ingen `AskUserQuestion` i økt 2 (målt: 0).
### Intervjuet
`AskUserQuestion` i økt 1: **5 runder, 12 spørsmål** (4 + 3 + 1 + 2 før briefen ble
promotert, 2 etter research: beslutning 6 og 7). `brief.md` oppgir
`interview_turns: 9`; tallet stemmer verken med runder eller spørsmål.
### Er brief.md avskrift av docs/build-brief.md?
Nei, målt tre måter (normaliserte linjer, små/store bokstaver og mellomrom slått sammen):
| Mål | Resultat |
|-----|----------|
| brief.md-linjer identiske med en build-brief-linje | 1 av 270 |
| brief.md-linjer ≥ 20 tegn med ≥ 0.8 likhet (difflib) mot en build-brief-linje | 4 av 236 |
| 8-gram (ordrekker på åtte) i brief.md som finnes i build-brief | 17 av 3 593 (0.5 %) |
| Ord | build-brief 2 301, brief.md 3 769 |
brief.md er en omskriving 1.6 ganger lengre enn kilden. Det nye i den er §14-svarene
(beslutning 1-5), beslutning 6-7 fra research, research-planen med tre tema, 33
grep-bare gate-kriterier for planen, og constraints omformulert for scope-guardian.
### Var `--quick` riktig modus?
`--quick` var PM-ordrens valg, ikke øktens (ordre 2026-09-03 punkt 3: «Kjoer
/trekbrief --quick med docs/build-brief.md som oppgavebeskrivelse»). Lest i
`commands/trekbrief.md`: `--quick` gir «compact start; still escalates on weak
sections», stiller framing-spørsmålet uansett, og hopper over fase 3.5
(effort-dialogen). Målt effekt i økt 1: eskaleringen slo inn, briefen gikk tre
brief-reviewer-runder (18:33, 18:39, 18:43) før gaten ble bestått; fase 3.5 ble
hoppet over, men `phase_signals` ble likevel skrevet for hånd etter beslutningen om
planleggingsmodell i runde 4. Hva standardmodus ville kostet, er en kontrafaktisk og
ikke målt; gatene er de samme i begge moduser.
### Hva ville `/trekplan --brief docs/build-brief.md` gitt?
Lest i `commands/trekplan.md` og målt mot validatoren:
```bash
node $VOYAGE/lib/validators/brief-validator.mjs --soft --json docs/build-brief.md
# {"valid": false, "errors": [{"code": "FM_MISSING", "message": "No frontmatter block found"}]} exit=1
```
- Fase 1 «Read the brief» parser frontmatter og henter `task`, `slug`,
`research_topics`, `research_status`; build-brief har ingen frontmatter, så alle
fire mangler. Validatoren gir en *error* (ikke warning) i både soft og strict modus,
og definisjonen sier «warnings do not block, errors do».
- Uten `research_status` finnes ingen research-gate og ingen research. De to
funnene som endret designet ville da manglet: Chrome ≥ 136 ignorerer
`--remote-debugging-port` på normalprofilen (research 02, operatøren kjører
Chrome 152), som gjør briefens §8 uutførbar som skrevet; og Cowork-sandkassen
når ikke Forgejo (research 03), som gjør `guard_ingest.py` uinstallerbar der.
Planen ville implementert §8 ordrett mot en nettleser som avviser den.
- Hard rule «Brief-driven … If a step has no brief basis, it is scope creep» og
«No interview» gjør at §14s fem beslutninger ikke kunne vært stilt i planfasen.
Konklusjon: build-brief er ikke et gyldig input for `/trekplan`; `/trekbrief` er
det eneste definerte steget som lager kontrakten validatoren krever.
## 4. Risiko før M1
### De to alvorlige blockerne
| Blocker | Løst i planen? | Arver M1 sesjon 1 (steg 1–3) den? |
|---------|----------------|-----------------------------------|
| 9, `zip -r` lekker `.git`, venv, `STATE.md`, `.claude/projects/` | Ja i stegtekst (steg 13, linje 514–527; steg 16, linje 607). Kommandoen står fortsatt i `brief.md:193` og `plan.md:103` | Nei. `awk 'NR>=122&&NR<=218' plan.md \| grep -i 'hook\|zip\|upload\|archive\|package'` → 0 treff. Sesjon 1s gjerde (2030–2031) nevner verken arkiv eller opplasting. Pakkeskriptet lages i steg 13, sesjon 4 |
| 10, PreToolUse-hook feilet åpent | Ja i stegtekst (steg 32, linje 1132/1138/1157–1160). Antakelse 7: om hooken i det hele tatt fyrer på connector-verktøy i Cowork er umålt; proben i steg 31 er ufullstendig (se rad 16 over) | Nei. Ingen hook, ingen `hooks/` i steg 1–3; `hooks/` er først berørbar i sesjon 8 (2086) |
Den reelle risikoen før M1 er ikke disse to. Den er at steg 1 ikke kan utføres av
utfører-økten (neste avsnitt), og at fire blockers er lukket delvis i steg som kommer
senere (13, 26, 21/25, 31), som M1 sesjon 4 og M3 sesjon 7–8 vil arve som de står.
### Steg 1: proben
Steg 1 måler fire ting: sesjonsmodus (lokal VM eller sky), om en plugin-deklarert
stdio-MCP-server dukker opp i økten, om en skill kan kalle `python3`, om
`${CLAUDE_PLUGIN_ROOT}` løses. Avgjørbarhet fra Claude Code, målt 2026-09-04:
| Spørsmål | Avgjørbart fra Claude Code? | Grunnlag |
|----------|-----------------------------|----------|
| Sesjonsmodus | Nei | `cowork_settings.json` på disk har bare nøkkelen `extraKnownMarketplaces`; skrivebordskonfigen har `coworkNetworkMode` og en liste over betrodde mapper, ingen sesjonslokasjon; den lokale sesjonslageret har 2 oppføringer, sist endret 2026-02-14 |
| Host-MCP synlig | Nei | krever en installert plugin med `.mcp.json` i en Cowork-økt |
| `python3` fra skill | Nei | krever en Cowork-økt |
| `CLAUDE_PLUGIN_ROOT` | Nei | krever en Cowork-økt |
Alle fire krever operatøren i Cowork. Steg 1 sier «operator-run measurement» og
«Reuses: the measurement method in research 03»; metoden der er en to-fils
test-plugin (én skill som ekkoer versjon, én stdio-server) lastet opp via
Customize → Plugins. Steget selv navngir ikke test-pluginen, og planens egen
`.mcp.json` (steg 12) og pakkeskript (steg 13) kommer elleve steg senere. En
utfører-økt kan ikke fullføre steg 1 alene; den kan bare forberede test-pluginen
og vente på operatørens fire svar.
Én til: den globale `CLAUDE.md` sier at Cowork er utilgjengelig på denne maskinen.
Research 03 målte det motsatte (Claude.app universal binary, Cowork-lager på disk).
Linjen er utdatert og bør rettes der den bor, ikke her.
## Metode og verifiseringslogg
Alle tall over er kjørt 2026-09-04. Kommandoene som ikke står inline:
- Transkripttidslinje og tokens: python over `*.jsonl` i øktens prosjektkatalog;
usage talt én gang per `message.id`; faser avgrenset på klokkeslettene for
`Skill`-kallene (`trekbrief` 18:27:42, `trekresearch` 18:46:29, `trekplan` 19:09:01).
- Anmeldernes unike funn: regex over JSON-objekter med `"severity"` i
underagent-transkriptene, unike på `(line, rule_key)`.
- Jaccard: `node`-script som importerer `lib/parsers/jaccard.mjs` og
`tokenize` fra `lib/review/plan-review-dedup.mjs`.
- Overlapp brief.md/build-brief: python `difflib.SequenceMatcher` og 8-gram-mengder.
- `plan-validator.mjs --strict --json plan.md` → valid, steps 56.
- Økt 2s gate-script (33 grep-kriterier fra brief.md) → PASS=33 FAIL=0.
- Sporbarhet og blocker-lukking: to Opus-underagenter med lese-tilgang; tabellene
deres er gjengitt i del 1 og 2, linjesitatene er stikkprøvet av hovedøkten.
Ikke målt: prosentandel kontekst (vindu ukjent), kostnad for standardmodus
`trekbrief` (kontrafaktisk), og hva Haiku-tokenene i websøk konkret ble brukt til.
## Revisjonen utført (2026-09-04, økt 4)
Operatøren svarte **(b)**: revider planen først. Ordre `20260904T135502Z-687411640-from-.claude`
navnga ti punkter; alle ti er utført i `plan.md` og `brief.md`
(`.claude/projects/2026-09-03-jobbsok-plugin-build/`). Begge filene er local-only —
`.gitignore:19` (`.claude/projects/`) — så denne seksjonen er den sporede bæreren av
endringen. Ingen kode er skrevet, ingen M1-steg er utført. **56 steg inn, 56 steg ut.**
| # | Punkt | Hva som faktisk står der nå |
|---|-------|-----------------------------|
| 1 | Steg 1, proben | Test-pluginen er navngitt `jobbsok-probe` (fire filer under `tests/fixtures/cowork-probe/`: manifest, `skills/probe-versjon/SKILL.md`, `.mcp.json` med `probe-tools`, `probe_tools.py`); steget sier eksplisitt at det ikke kan fullføres av en utfører-økt; de fire spørsmålene er en tabell operatøren besvarer, forhåndsutfylt `ubesvart`; Verify er `test "$(grep -cE …)" = 4`, som feiler på et ubesvart punkt i stedet for å telle og se en annen vei |
| 2 | Steg 13, `BUILD_STAMP` | `.gitignore` er nå leveranse: i `expected_paths`, i `must_contain` og i testen (`git check-ignore BUILD_STAMP`). Testtallet 6 → 7 |
| 3 | Steg 20/21, `--oppdater` | «The script writes nothing: it is a reader» er borte; `--oppdater` er en navngitt modus med egen test (kun de fire cachede nøklene endres, resten byte-identisk). Steg 21s skill-kall har test og `must_contain`. Testtallet 7 → 8 |
| 4 | Steg 23, `dagens`-ekkoet | Skillen ekkoer `BUILD_STAMP` + `plugin.json`-versjon på forespørsel (ikke i den gyldne dagsvisningen, som ellers ville brutt per commit). Testtallet 5 → 6 |
| 5 | Steg 26, benign-korpus | Korpuset er de åtte annonsene i `tests/fixtures/listings/` fra steg 7 (finnes fra M1, nitten steg før), ikke `adv-07-benign.json` fra steg 29. Taket er **1 av 8 (12,5 %)**, uttalt som snubletråd og ikke som måling; overskridelse eskalerer, taket heves aldri for å passe resultatet |
| 6 | Steg 31, connector-hook-proben | Femte punkt `- Connector-hook:` i probefila; Verify feiler mens den står `ubesvart`; `docs/cowork-probe.md` i `expected_paths` og i sesjon 8s gjerde |
| 7 | `--check` i Cowork-stegene | 5 av 6, ikke 6 av 6 — se avvik A |
| 8 | Pass 2 + graden | `## Adversarial Pass 2 (v5.1.1 high-effort)` med «unavailable, skipped» — se avvik C. Graden er merket **egenvurdert** i planhodet, med REPLAN 65.8 navngitt som eneste anmelder-verdict |
| 9 | Revisions rad 7 | «Decided YES by the operator 2026-09-04»; avviksnoten er nå målt, ikke påstått — se avvik B |
| 10 | Foreldet tekst | `brief.md` 193–194 og 245, `plan.md` 103. Ingen av dem sier lenger `zip -r` eller «the version-echo skill» som instruks. `interview_turns` 9 → 5 (målt: 5 runder / 12 spørsmål) |
### Gater ved levering (kjørt 2026-09-04, økt 4)
| Gate | Resultat |
|------|----------|
| `plan-validator.mjs --strict --json plan.md` | `valid: true`, `steps: 56`, 0 errors, 0 warnings |
| `brief-validator.mjs --json brief.md` | `valid: true`, 0 errors, 0 warnings |
| Økt 2s gate-script (33 grep-kriterier fra brief.md) | PASS=33 FAIL=0 |
| `grep -c 'Pass 2' plan.md` | 6 (≥ 1) |
| De tolv «Foreldet tekst»-greppene | PASS=12 FAIL=0 |
Gate-scriptene er gjenskapt og ligger i øktens scratchpad, ikke i repoet. De tolv greppene
måler **levende instruksjonstekst**: `## Revisions`-loggen og de to stedene som siterer
briefens frase for å ta avstand fra den er utelatt ved konstruksjon, ikke ved skjønn.
Begge de to spørringene er validert mot et kjent-positivt tilfelle (1 treff før filtrering,
0 etter) — et «fant ingenting» som ikke er verifisert, er ikke en måling.
### Tre avvik fra ordreteksten, uttalt
**A. Punkt 7 er utført som 5 av 6, ikke 6 av 6.** Ordren sier «alle seks
`Verifiser i Cowork`-steg kjører `--check`». Steg 16 er M1s gate, og
`scripts/sak_status.py` opprettes først i steg 17, i M2. Å skrive `--check` inn i steg 16
ville lagt en kommando mot et script som ikke finnes. Steg 25, 37, 42, 47 og 56 kjører den
nå — i Verify og i stegteksten. Unntaket er skrevet inn i steg 16 med begrunnelsen, og
Revisions rad 15 sier nå rett ut at påstanden «every Cowork step now runs `--check`» var
usann da den ble skrevet.
**B. Punkt 9s tolvte script er `jobbsok_tools.py`, ikke `kandidat_schema.py`.**
`kandidat_schema.py` sto allerede først i avviksnotens liste over elleve. Målt på nytt her:
`grep -o 'scripts/[A-Za-z0-9_./-]*' plan.md | sed 's/[.,)]*$//' | sort -u` gir 25 oppføringer,
hvorav to er de bare katalogstiene `scripts/` og `scripts/jobbsok_lib/` — altså **23 filer**.
Det forklarer både rapportens 23 (filer) og PM-ens 25 (oppføringer): begge tallene er riktige
for hver sin nevner. Fordelingen: 3 i briefens §4, **12** kapabilitets-scripts (den manglende
er `jobbsok_tools.py`), 4 moduler i `jobbsok_lib/`, **4** shell-hjelpere (noten sa «two»).
Noten er skrevet om med måletallene og kommandoen som ga dem.
**C. Pass 2-seksjonen står sist i fila, ikke i planhodet.** Ordren sier «planhodet … slik
`commands/trekplan.md` krever»; kommandodefinisjonen sier «Append the section header to
plan.md **before the trailing JSON block**». Planen har ingen avsluttende JSON-blokk, så
seksjonen er lagt til slutt, der den anvisningen peker. Planhodet har fått en peker til den
i samme setning som merker graden egenvurdert, så begge lesningene av ordren er dekket.
### Ett bifunn, ikke utført
Gate-scriptet fra økt 2 lå i en scratchpad og var nesten borte; det er gjenskapt herfra, men
ligger igjen i en scratchpad. De to scriptene (33 gater, 12 grep) er den eneste maskinelle
sjekken på at denne revisjonen holder over tid. Å legge dem under `docs/` eller `scripts/`
er ikke en del av ordren og er ikke gjort — det er et spørsmål til operatøren.