@haus-tech/haus-workflow 4.8.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +47 -0
- package/dist/cli.js +1883 -902
- package/docs/before-you-start.md +57 -0
- package/docs/glossary.md +56 -0
- package/library/catalog/manifest.json +97 -34
- package/library/global/agents/request-assessor.md +2 -2
- package/library/global/agents/request-scorer.md +14 -9
- package/library/global/agents/request-specifier-eskalerad.md +1 -1
- package/library/global/agents/request-specifier.md +1 -1
- package/library/global/skills/haus-workflow/references/new.md +18 -11
- package/library/global/skills/request/SKILL.md +731 -127
- package/library/global/skills/request/scripts/archive.mjs +1376 -0
- package/library/global/skills/request/scripts/check-lasta.mjs +64 -0
- package/library/global/skills/request/scripts/compare-scores.mjs +73 -15
- package/library/global/skills/request/scripts/contract-check.mjs +110 -49
- package/library/global/skills/request/scripts/lib.mjs +81 -0
- package/library/global/skills/request/scripts/precheck.mjs +30 -27
- package/library/global/skills/request/scripts/report.mjs +571 -0
- package/library/global/skills/request/scripts/resolve-anchors.mjs +243 -0
- package/library/global/skills/request-assess-impact/SKILL.md +10 -10
- package/library/global/skills/request-score/SKILL.md +19 -10
- package/library/global/skills/request-sync/SKILL.md +4 -4
- package/library/global/skills/request-write-spec/SKILL.md +6 -6
- package/library/global/skills/request-write-spec/references/specformat.md +2 -2
- package/package.json +5 -2
- package/library/global/agents/request-classifier.md +0 -55
- package/library/global/skills/request/scripts/compare-classifications.mjs +0 -94
- package/library/global/skills/request-classify/SKILL.md +0 -79
- package/library/global/skills/request-classify/references/klassningsinstruktion.md +0 -152
|
@@ -1,27 +1,29 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: request
|
|
3
|
-
description: Enda ingången till Haus requestflöde. Använd när användaren säger "/request", "kör requestflödet", "speca och bedöm", "prisa den här posten", "ta önskemålet hela vägen", "vad ligger i kön", "detaljer <post>", eller när flera request-skills ska kedjas i en följd. Enskilda request-skills (request-write-spec, request-
|
|
3
|
+
description: Enda ingången till Haus requestflöde. Använd när användaren säger "/request", "kör requestflödet", "speca och bedöm", "prisa den här posten", "ta önskemålet hela vägen", "vad ligger i kön", "detaljer <post>", eller när flera request-skills ska kedjas i en följd. Enskilda request-skills (request-write-spec, request-score m.fl.) fungerar fortfarande fristående; den här skillen äger kedjan, arkivet och dispatchen till subagenter.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# /request — requestflödets ingång
|
|
7
7
|
|
|
8
|
-
Tunn orkestrering ovanpå de
|
|
9
|
-
**noll domänregler**: allt om specformat,
|
|
8
|
+
Tunn orkestrering ovanpå de fyra request-skillsen. Den här skillen innehåller
|
|
9
|
+
**noll domänregler**: allt om specformat, poäng och Asana-fält bor i
|
|
10
10
|
respektive skill. Här bor bara routing, kontextbärande, arkivet och dispatchen.
|
|
11
11
|
|
|
12
12
|
## Uppgifter
|
|
13
13
|
|
|
14
14
|
`/request [uppgift]` — utan argument: visa menyn nedan.
|
|
15
15
|
|
|
16
|
-
| Uppgift | Gör
|
|
17
|
-
| -------------------------------------- |
|
|
18
|
-
| `speca <önskemål eller gid>` | Källmanifest → dispatcha `request-specifier` → arkivera spec + granskarblock
|
|
19
|
-
| `bedöm <gid, slug eller nr>` | Grind → säkra analys → dispatcha `request-
|
|
20
|
-
| `status` | Kö-läge via request-sync, BLUF-tabell med radnummer
|
|
21
|
-
| `godkänn <nr eller gid>` | Flytta Offer status framåt via request-sync — se grindavsnittet
|
|
22
|
-
| `underkänn <nr eller gid> <skäl>` | Skäl som Asana-kommentar + iterationsräknare via request-sync
|
|
23
|
-
| `
|
|
24
|
-
| `
|
|
16
|
+
| Uppgift | Gör |
|
|
17
|
+
| -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
|
18
|
+
| `speca <önskemål eller gid>` | Källmanifest → dispatcha `request-specifier` → arkivera spec + granskarblock |
|
|
19
|
+
| `bedöm <gid, slug eller nr>` | Grind → säkra analys → dispatcha `request-scorer` → arkivera JSON |
|
|
20
|
+
| `status` | Kö-läge via request-sync, BLUF-tabell med radnummer |
|
|
21
|
+
| `godkänn <nr eller gid>` | Flytta Offer status framåt via request-sync — se grindavsnittet |
|
|
22
|
+
| `underkänn <nr eller gid> <skäl>` | Skäl som Asana-kommentar + iterationsräknare via request-sync |
|
|
23
|
+
| `döm <post>` | Människodom vid OLIKA: välj körning, beställ omkörning eller underkänn underlaget |
|
|
24
|
+
| `detaljer <gid, slug eller nr> [steg]` | Skriv ut arkiverad JSON/dokument för posten |
|
|
25
|
+
| `utvärdera <post…> <modell…>` | Kör flödet en gång per namngiven modell mot experimentytan, minst en modell; `sammanställ` ger svepvyn, `rapport` en läsbar jämförelse |
|
|
26
|
+
| `hjälp` | Förklara uppgifterna, rör inga filer |
|
|
25
27
|
|
|
26
28
|
## Hårda regler
|
|
27
29
|
|
|
@@ -31,25 +33,46 @@ respektive skill. Här bor bara routing, kontextbärande, arkivet och dispatchen
|
|
|
31
33
|
Skill-verktyget (`request-sync`).
|
|
32
34
|
- **En skrivare i taget mot Asana.** Batchresultat skrivs tillbaka sekventiellt,
|
|
33
35
|
en post i taget, aldrig parallellt.
|
|
34
|
-
- **Dokument klistras bytetroget** in i
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
- **Dokument klistras bytetroget** in i specifier- och assessor-prompter
|
|
37
|
+
(önskemål, spec, granskarblock). En trunkerad eller omformaterad
|
|
38
|
+
inklistring flyttar källtexten under agentens fötter och ger tyst fel
|
|
39
|
+
svar. Klistra aldrig in en sammanfattning.
|
|
40
|
+
- **Prissättningens underlag pekas ut per sökväg (ADR-0099).** Scorerns
|
|
41
|
+
prompt bär två namngivna absoluta sökvägar (`spec.md`, `impact.md`) i
|
|
42
|
+
stället för inklistrad text — agenten läser filerna själv via Read, så
|
|
43
|
+
ingen avskrift kan trunkeras, och beläggens ankare (källa + delsträng)
|
|
44
|
+
löses av scripten mot exakt samma filer på disk. Läs-scopet är EXAKT
|
|
45
|
+
dessa två filer plus skillens egen katalog, aldrig
|
|
46
|
+
körningskatalogen som helhet: `granskarblock.md` är assessorns underlag
|
|
47
|
+
och äldre pricing-JSON vore ren kontaminering av dubbelkörningens
|
|
48
|
+
oberoende.
|
|
49
|
+
- **Prislistan och repot hålls borta från scorern.** Dess
|
|
50
|
+
agentdefinition saknar sök- och shellverktyg (Grep/Glob/Bash), och Read
|
|
51
|
+
är promptbegränsad enligt regeln ovan — läs-scopet är en promptregel,
|
|
40
52
|
inte en fysisk spärr. Därför: lägg aldrig prislistans innehåll i prompten,
|
|
41
53
|
och lägg inga egna sökvägar i dispatcherns rader utöver etiketterna i mallen.
|
|
42
|
-
Sökvägar som redan står i
|
|
54
|
+
Sökvägar som redan står i underlaget (analysen namnger filer,
|
|
43
55
|
det är dess jobb) är inte ett brott — regeln gäller det dispatchern
|
|
44
56
|
lägger till. Granska `LÄSTA:`-raden i svaret (se dispatch-kontraktet).
|
|
45
57
|
- **Granskarblocken når aldrig kunden.** Specens granskarblock arkiveras separat
|
|
46
58
|
(`granskarblock.md`). Analysens "## Till granskaren"-block ligger kvar i
|
|
47
|
-
`impact.md` (det är del av underlaget för
|
|
59
|
+
`impact.md` (det är del av underlaget för poängsättningen) — men inget
|
|
48
60
|
granskarblock får någonsin skickas med i material som går till request-sync
|
|
49
61
|
för kundsynliga fält.
|
|
50
62
|
- **Arkivet är cache, Asana är sanningen.** Vid konflikt vinner brädan.
|
|
51
63
|
- **Godkännande antas aldrig.** Att en spec finns i arkivet betyder inte att den
|
|
52
64
|
är granskad. Se grinden under `bedöm`.
|
|
65
|
+
- **Experimentdata når aldrig Asana.** `utvärdera` skriver aldrig via
|
|
66
|
+
request-sync; dess enda Asana-kontakt är läsande hämtning av önskemålet i
|
|
67
|
+
huvudkonversationen. `experiments/`-trädet är inte postkataloger: sync,
|
|
68
|
+
batch och guard läser bara `.haus/requests/<gid-eller-slug>/` på toppnivån
|
|
69
|
+
och rör aldrig `experiments/`.
|
|
70
|
+
- **Maskinen kör om enbart vid scriptbevisat kontraktsbrott.** Omdispatch
|
|
71
|
+
(budget EN per agent) svarar på ett fel som precheck, resolve-anchors eller
|
|
72
|
+
contract-check har bevisat. En oenighet mellan två GILTIGA körningar är en
|
|
73
|
+
bedömningsfråga och går alltid till människan via uppgiften `döm`: fler
|
|
74
|
+
maskinkörningar producerar fler röster, aldrig mer sanning. Ingen ny
|
|
75
|
+
omkörningsmekanism får läggas till som bryter mot detta.
|
|
53
76
|
|
|
54
77
|
## Arkivet: `.haus/requests/`
|
|
55
78
|
|
|
@@ -57,8 +80,8 @@ Orkestreringens kuvert. De haus-hanterade request-skillsen känner inte till det
|
|
|
57
80
|
den här skillen (och agenterna via sina prompter) underhåller det.
|
|
58
81
|
|
|
59
82
|
**En katalog = en spec = en prissättningsbar post.** En bunt (flera specar ur
|
|
60
|
-
samma önskemål) blir flera kataloger —
|
|
61
|
-
|
|
83
|
+
samma önskemål) blir flera kataloger — poängen sätts per post, så en katalog
|
|
84
|
+
med flera specar går inte att bedöma.
|
|
62
85
|
|
|
63
86
|
```
|
|
64
87
|
<repo-rot>/.haus/requests/<gid-eller-slug>/
|
|
@@ -67,13 +90,22 @@ och poängen sätts per post, så en katalog med flera specar går inte att bed
|
|
|
67
90
|
│ kopieras till varje delkatalog)
|
|
68
91
|
├── impact.md påverkansanalysen, ordagrann inkl. sitt
|
|
69
92
|
│ Till granskaren-block
|
|
70
|
-
├──
|
|
71
|
-
├── score-
|
|
72
|
-
|
|
73
|
-
├── score-guard-vN.json
|
|
93
|
+
├── score-pricing-vN.json nytt varv = ny fil, skriv aldrig över
|
|
94
|
+
├── score-guard-vN.json guard-utfall synkas aldrig, bara arkiveras
|
|
95
|
+
│ (egen N-sekvens per typ, skild från pricing)
|
|
74
96
|
└── state.json
|
|
75
97
|
```
|
|
76
98
|
|
|
99
|
+
Äldre arkiv (före ADR-0098) bär även `classification-pricing-vN.json` /
|
|
100
|
+
`classification-guard-vN.json` från den borttagna klassaxeln. De läses och
|
|
101
|
+
visas som förut (`detaljer`, rapporten, `archive.mjs`) men skrivs aldrig av
|
|
102
|
+
nya körningar.
|
|
103
|
+
|
|
104
|
+
Förkastade försök bär `-avvisad`-suffix och står utanför N-räkningen:
|
|
105
|
+
prissättningens `<typ>-pricing-vN-avvisad.json` och textstegens
|
|
106
|
+
`spec-avvisad-<datum>.md` / `impact-avvisad-<datum>.md` (ADR-0099) — se
|
|
107
|
+
omdispatch-regeln i dispatch-kontraktet.
|
|
108
|
+
|
|
77
109
|
- Katalognamn: Asana-gid när posten finns på brädan, annars en kebab-slug av
|
|
78
110
|
spec-rubriken. Bunt utan gid: `<slug>-1`, `<slug>-2`, … När gid myntas senare:
|
|
79
111
|
döp om katalogen till gid och notera sluggen i `state.json.former_slug`.
|
|
@@ -94,6 +126,7 @@ och poängen sätts per post, så en katalog med flera specar går inte att bed
|
|
|
94
126
|
"bundle": { "parent_slug": null, "part": null, "of": null },
|
|
95
127
|
"split": { "parent": null, "part": null, "of": null },
|
|
96
128
|
"approval": null,
|
|
129
|
+
"granskarutslag": [],
|
|
97
130
|
"note": null,
|
|
98
131
|
"runs": []
|
|
99
132
|
}
|
|
@@ -106,14 +139,44 @@ och poängen sätts per post, så en katalog med flera specar går inte att bed
|
|
|
106
139
|
`{ "source": "asana" | "manual", "by": "<namn, krävs vid manual>",
|
|
107
140
|
"status_read": "<värde>", "date": "YYYY-MM-DD" }`.
|
|
108
141
|
Anteckningen är spårbarhet, aldrig själva godkännandet.
|
|
142
|
+
- `granskarutslag` är en lista, en rad per dom, skriven via `archive.mjs utslag`, aldrig för hand.
|
|
143
|
+
Radform: `{ "typ": "viktning" | "kalibrering" | "sakandring", "date": "YYYY-MM-DD", "beslutad_av": "<namn>", ... }`.
|
|
144
|
+
Viktning bär dessutom `beslut` (ordagrant), `axel` (`score`; `classification`
|
|
145
|
+
förekommer i äldre arkiv), `n` och `galler_fil`: raden ÄR spärrlyftet,
|
|
146
|
+
`archive.mjs sparr` läser den.
|
|
147
|
+
Kalibrering bär `fraga`, `lasning1`, `lasning2`: en notis om att en
|
|
148
|
+
protokollfråga lät två giltiga läsningar divergera, underlag för nästa
|
|
149
|
+
instruktionsversion. Sakändring bär `beslut`: kvittot i `state.json` för
|
|
150
|
+
samma händelse som citatblocket i `impact.md` (se `döm`, vägen "Underlaget
|
|
151
|
+
är fel"). Det ordagranna beslutet bor i citatblocket, raden här är bara
|
|
152
|
+
revisionsspåret, aldrig underlaget självt.
|
|
153
|
+
Listan läses medvetet ALDRIG tillbaka in i någon prompt, oavsett typ: ett
|
|
154
|
+
utslag som når agenterna styr nästa bedömning i stället för att dokumentera
|
|
155
|
+
den föregående. Nollas (töms) vid respec, av samma skäl som `approval`
|
|
156
|
+
nollas (se `speca` steg 5): ett utslag mot en ersatt spec är inte längre
|
|
157
|
+
giltigt. Bor ENDAST i `state.json`. Rader skrivs aldrig om.
|
|
109
158
|
- `runs[]` får en rad per dispatch, även spec- och analyskörningar:
|
|
110
159
|
`{ "file": "spec.md" | "impact.md" | "<run>.json", "skill": "...",
|
|
111
|
-
"agent": "...",
|
|
160
|
+
"agent": "...",
|
|
161
|
+
"model": { "uppgiven": "<ur MODELL-svansraden>", "fakturerad": "<känd fakturerad modell, annars null>" },
|
|
162
|
+
"effort": "<ur agentdefinitionen>",
|
|
112
163
|
"date": "YYYY-MM-DD",
|
|
113
164
|
"reference_sha256": { "<referensfil>": "<sha256>" },
|
|
114
165
|
"underlag_sha256": { "spec.md": "<sha256>", "impact.md": "<sha256>" },
|
|
115
|
-
"double_run": "bekräftad" | "olika" | null,
|
|
116
|
-
"superseded_by": null }`.
|
|
166
|
+
"double_run": "bekräftad" | "olika" | "tolerans" | null,
|
|
167
|
+
"superseded_by": null, "partial_rerun": false, "pairs_with": null }`.
|
|
168
|
+
`model` bär två fält (ADR-0099): `uppgiven` är agentens självrapport ur
|
|
169
|
+
MODELL-svansraden, `fakturerad` fylls när dispatchern känner den
|
|
170
|
+
fakturerade modellen (`add-run --fakturerad`), annars `null` — faktureringens
|
|
171
|
+
sanning per körning bor i `proveniens.fakturerade_modeller`. Äldre arkiv bär
|
|
172
|
+
`model` som ren sträng och läses som förut.
|
|
173
|
+
`quote_repairs` förekommer i äldre arkiv (före ADR-0092) och läses men
|
|
174
|
+
skrivs aldrig av nya körningar.
|
|
175
|
+
Stämplingen görs alltid via `archive.mjs add-run`; hur N räknas ut, vilket
|
|
176
|
+
suffix en fil får och hur en riktad omkörnings parning skrivs bor i
|
|
177
|
+
scriptet och testerna. VILKA `--typ` som skickas till `archive.mjs next-n`,
|
|
178
|
+
alltså vilka axlar som faktiskt kördes i varvet, är fortfarande
|
|
179
|
+
orkestratorns beslut, inte scriptets.
|
|
117
180
|
`underlag_sha256` är underlagsproveniensen: hashen för de dokument körningen
|
|
118
181
|
faktiskt såg. Precheck vägrar bedöma när analysens spec-hash inte matchar
|
|
119
182
|
nuvarande `spec.md`, och guard ska vägra diffa mot en körning vars underlag
|
|
@@ -125,12 +188,75 @@ och poängen sätts per post, så en katalog med flera specar går inte att bed
|
|
|
125
188
|
alla arkiverade körningar. Samma verktyg används för `underlag_sha256`.
|
|
126
189
|
Referensfilerna ligger under Claude-konfigkatalogen (`CLAUDE_CONFIG_DIR`
|
|
127
190
|
eller `~/.claude`). En senare guard-körning jämför hash och vägrar diffa vid
|
|
128
|
-
skevhet ("
|
|
191
|
+
skevhet ("ompoängsättning krävs, skalan har ändrats").
|
|
129
192
|
- `status` blir ALDRIG `priced` när något stopputfall finns i varvets
|
|
130
|
-
körningar, eller när
|
|
193
|
+
körningar, eller när den GÄLLANDE raden har `double_run: "olika"` olyft, eller
|
|
194
|
+
när den gällande raden bär `partial_rerun: true` utan en matchande
|
|
195
|
+
dom (en beställd omkörning väntar på granskaren, se uppgiften `döm`).
|
|
196
|
+
`archive.mjs sparr` avgör bägge skälen identiskt (`sparrSkal`).
|
|
197
|
+
Spärren lyfts av ett viktningsutslag (`archive.mjs sparr` är den enda tolken,
|
|
198
|
+
se uppgiften `döm`) eller av en beställd omkörning vars dom landat i ett
|
|
199
|
+
viktningsutslag; ingen annan väg lyfter den, och den oeniga axelns äldre
|
|
200
|
+
rader skrivs aldrig om även efter lyft.
|
|
201
|
+
`double_run: "tolerans"` räknas som bekräftad och blockerar inte `priced`.
|
|
202
|
+
I äldre arkiv som bär en klassaxel (före ADR-0098) vägrar
|
|
203
|
+
`archive.mjs set-status priced` därutöver ett OFULLSTÄNDIGT par:
|
|
204
|
+
klass- och poängaxelns gällande varvnummer skiljer sig utan att skillnaden
|
|
205
|
+
är en förklarad enaxlig omkörning (`partial_rerun: true` på den högre
|
|
206
|
+
axelns gällande rad), eller poängaxeln saknas helt. Ett arkiv utan
|
|
207
|
+
klassaxel prövas aldrig mot par-regeln — poängen är den enda axeln.
|
|
208
|
+
Det här skälet prövas av `pricedBlockers` (`archive.mjs set-status`),
|
|
209
|
+
inte av `archive.mjs sparr` — reglerna bor i scriptet och dess tester.
|
|
131
210
|
- `spec_synced` sätts av speca steg 7 (posten lagd på brädan);
|
|
132
211
|
`guard_run` reserveras för guard-kommandot (senare byggsteg).
|
|
133
212
|
|
|
213
|
+
### Experimentytan: `experiments/`
|
|
214
|
+
|
|
215
|
+
Modellkörningar från `utvärdera` bor i ett eget träd och är aldrig prisposter:
|
|
216
|
+
|
|
217
|
+
```
|
|
218
|
+
<repo-rot>/.haus/requests/experiments/<slug>/
|
|
219
|
+
├── experiment.json ticketreferens, datum, modellista, manifest-hash,
|
|
220
|
+
│ status per körning
|
|
221
|
+
├── <modell>/ `default` som modellvärde ger katalognamnet
|
|
222
|
+
│ `baseline/`
|
|
223
|
+
│ ├── k1/
|
|
224
|
+
│ ├── k1/korning.json headless-svaret RÅTT: USD, tokens, dispatcher
|
|
225
|
+
│ ├── k1/matning.json startarens egen mätning: startad, avslutad, wall_ms
|
|
226
|
+
│ ├── k2/ senare körning av SAMMA modell
|
|
227
|
+
│ └── k2/del-1/ … delkataloger vid DELA_UPP
|
|
228
|
+
└── <annan modell>/k1/ …
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
- **Två filer, två ägare.** `korning.json` är headless-svaret ordagrant och
|
|
232
|
+
ägs av CLI:n; `matning.json` är startarens klocka och ägs av oss. En
|
|
233
|
+
haus-nyckel inne i `korning.json` skulle göra den till ett blandat format
|
|
234
|
+
som inte längre går att ställa mot CLI:ns egen utdata.
|
|
235
|
+
- **Ingen körning skrivs någonsin över.** Värdet i en gammal körning är att
|
|
236
|
+
kunna jämföra samma modell före och efter en ändring i skillen eller
|
|
237
|
+
agentprompterna; skriver en ny körning över den är den jämförelsen borta för
|
|
238
|
+
alltid. Varje körning får därför en egen katalog `k<N>` under sin modell.
|
|
239
|
+
- **Körningskatalogen ÄR postkatalogen.** Den följer arkivkontraktet
|
|
240
|
+
bytetroget (spec.md, granskarblock.md, impact.md, pricing-JSON, state.json,
|
|
241
|
+
`runs[]`-reglerna), så `precheck.mjs` och `contract-check.mjs` fungerar
|
|
242
|
+
oförändrade, de pekas bara på `<modell>/k<N>/`. Proveniensen följer med gratis.
|
|
243
|
+
- **Numret allokeras aldrig av skillen själv**, alltid med
|
|
244
|
+
`archive.mjs ny-korning <modellkatalog>`, som skapar katalogen
|
|
245
|
+
atomiskt och skriver dess sökväg. Två samtidiga processer, till exempel två
|
|
246
|
+
Claude-konton mot samma checkout, får då `k2` och `k3`, aldrig samma katalog.
|
|
247
|
+
Räknar skillen själv förlorar den ena processens körning tyst.
|
|
248
|
+
- `state.json` i en körningskatalog bär markören `"experiment": true`.
|
|
249
|
+
`approval` förblir `null` och `status` blir ALDRIG `priced`: ett
|
|
250
|
+
experimentresultat kan inte förväxlas med en prispost.
|
|
251
|
+
- Katalognamnet `experiments` är reserverat: en spec vars rubrik skulle sluggas
|
|
252
|
+
till `experiments` får suffixet `-post`.
|
|
253
|
+
- `experiment.json` bär `varianter: []` i deklarationsordning och `status` per
|
|
254
|
+
körning: `"klar"`, `"ofärdig"`, `"stopp"`, `"väntar på dom"`. Literalerna
|
|
255
|
+
skrivs exakt så, mellanslag och diakritiska tecken inkluderade. Äldre filer
|
|
256
|
+
med `baselinemodell` och `kandidatmodell` läses utan fel; nya skrivningar
|
|
257
|
+
använder bara `varianter`.
|
|
258
|
+
- `experiments/` ärver gitignore-skyddet från `.haus/requests/`.
|
|
259
|
+
|
|
134
260
|
## Uppgift: `speca`
|
|
135
261
|
|
|
136
262
|
1. **Underlag.** Rått önskemål inklistrat, eller ett gid — hämta då posten via
|
|
@@ -154,16 +280,31 @@ och poängen sätts per post, så en katalog med flera specar går inte att bed
|
|
|
154
280
|
kopieras till varje katalog som `granskarblock.md`). Bunt ur en gid-post:
|
|
155
281
|
del 1 behåller gid-katalogen, resterande delar får slug-kataloger med
|
|
156
282
|
`bundle.parent_slug` satt till gid:t; syskontasks på brädan mintas först
|
|
157
|
-
vid sync.
|
|
158
|
-
|
|
283
|
+
vid sync. Stämpla varje berörd `state.json` med
|
|
284
|
+
`node <skillkatalog>/scripts/archive.mjs add-run <katalog> --file spec.md
|
|
285
|
+
--skill request-write-spec --agent <request-specifier|request-specifier-eskalerad>
|
|
286
|
+
--model <ur MODELL-svansraden> --ref references/specformat.md=<hash via ref-hash.mjs
|
|
287
|
+
på request-write-spec/references/specformat.md>`. Scriptet sätter
|
|
288
|
+
`underlag_sha256` tomt, en spec har inget underlag i repot — men
|
|
289
|
+
referens-hashen måste sättas explicit precis som för poängen, annars
|
|
290
|
+
tappas specformatets proveniens (se runs-kontraktet).
|
|
159
291
|
**Respec över befintlig katalog invaliderar analysen:** när `spec.md`
|
|
160
292
|
ersätts döps ev. `impact.md` om till `impact-superseded-<datum>.md`,
|
|
161
|
-
status sätts till `spec_draft
|
|
162
|
-
ogranskad per definition,
|
|
163
|
-
|
|
293
|
+
status sätts till `spec_draft`, `approval` nollas och `granskarutslag`
|
|
294
|
+
töms — en ny spec är ogranskad per definition, ett utslag mot en ersatt
|
|
295
|
+
spec är inte längre giltigt, och en gammal analys mot ny spec är exakt
|
|
296
|
+
den skevhet proveniens-kontrollen finns för att stoppa.
|
|
164
297
|
6. **Formkontroll.** Kör `node <skillkatalog>/scripts/precheck.mjs <katalog>`
|
|
165
298
|
per katalog. BRISTER i spec/granskarblock → dispatcha om specifiern EN gång
|
|
166
|
-
enligt omdispatch-regeln
|
|
299
|
+
enligt omdispatch-regeln. **Det förkastade utkastet får kvitto
|
|
300
|
+
(ADR-0099, samma regel som prissättningens `-avvisad`):** arkivera det
|
|
301
|
+
som `spec-avvisad-<datum>.md` innan omdispatchen, och stämpla det med en
|
|
302
|
+
egen runs-rad via `archive.mjs add-run --file spec-avvisad-<datum>.md
|
|
303
|
+
--note "<kontrollens felrader>"` (övriga flaggor som spec-radens). VARJE
|
|
304
|
+
dispatch får sin egen runs-rad — även den förkastade — så arkivet bär
|
|
305
|
+
både att ett omtag skedde och varför; en spec godkänd i andra försöket
|
|
306
|
+
får aldrig se ut som en som blev rätt direkt.
|
|
307
|
+
BRISTER i `state.json` är wrapperns egna filer och
|
|
167
308
|
rättas av wrappern själv, aldrig via omdispatch. Kvarstår brister, visa dem
|
|
168
309
|
och stanna. VARNING:ar visas men stoppar inget.
|
|
169
310
|
7. **Svara BLUF:** en rad per spec (rubrik + ev. flaggor), sedan granskarblocket
|
|
@@ -174,8 +315,8 @@ och poängen sätts per post, så en katalog med flera specar går inte att bed
|
|
|
174
315
|
|
|
175
316
|
## Uppgift: `bedöm`
|
|
176
317
|
|
|
177
|
-
Kör prissättningsbenet: påverkansanalys om den saknas, sedan
|
|
178
|
-
|
|
318
|
+
Kör prissättningsbenet: påverkansanalys om den saknas, sedan poängsättning med
|
|
319
|
+
driftvakt.
|
|
179
320
|
|
|
180
321
|
1. **Grind — obligatorisk, aldrig överhoppbar.** Bedömning kräver en granskad
|
|
181
322
|
spec, och godkännandet bor i Asana:
|
|
@@ -209,77 +350,110 @@ oenighetsgrind.
|
|
|
209
350
|
skickas med som internt underlag (samma förtroendedomän; flaggorna där är
|
|
210
351
|
ofta analysens viktigaste ingång). Arkivera svaret som `impact.md`
|
|
211
352
|
(inklusive dess "## Till granskaren"-block — visa blocket för användaren,
|
|
212
|
-
aldrig till kundfält),
|
|
213
|
-
`
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
353
|
+
aldrig till kundfält), stämpla med
|
|
354
|
+
`node <skillkatalog>/scripts/archive.mjs add-run <katalog> --file impact.md
|
|
355
|
+
--skill request-assess-impact --agent request-assessor
|
|
356
|
+
--model <ur MODELL-svansraden>` (scriptet sätter `underlag_sha256` mot
|
|
357
|
+
`spec.md`). Kör precheck igen med `--impact`. Fäller precheck det nya
|
|
358
|
+
utkastet → omdispatcha assessorn EN gång enligt omdispatch-regeln, och ge
|
|
359
|
+
det förkastade utkastet kvitto precis som i speca steg 6: arkivera det som
|
|
360
|
+
`impact-avvisad-<datum>.md` och stämpla en egen runs-rad med kontrollens
|
|
361
|
+
felrader i `--note` (ADR-0099).
|
|
362
|
+
4. **Prissättning.** Dispatcha `request-scorer` enligt promptmallen.
|
|
363
|
+
Ingen prislista, inget repo, inga andra posters dokument i prompten.
|
|
364
|
+
5. **Ankarlösning och kontraktskontroll.** Strippa svansraderna (`MODELL:`,
|
|
365
|
+
`LÄSTA:`, ev. `AVVIKELSE:`) ur svaret. Kör
|
|
366
|
+
`node <skillkatalog>/scripts/check-lasta.mjs "<LÄSTA-radens innehåll>" <spec.md> <impact.md>`
|
|
367
|
+
(exit 1 = kontraktsbrott, se dispatch-kontraktet). Skriv sedan den rena
|
|
368
|
+
JSON:en till fil och kör i ordning:
|
|
369
|
+
`node <skillkatalog>/scripts/resolve-anchors.mjs <svar.json> <spec.md> <impact.md>`
|
|
370
|
+
(löser beläggsankare till ordagranna källblock; OLÖST/FLERTYDIG är ett
|
|
371
|
+
kontraktsbrott), sedan
|
|
372
|
+
`node <skillkatalog>/scripts/contract-check.mjs <svar.json> <spec.md> <impact.md> --expect-id <katalogens id>`.
|
|
373
|
+
BROTT från något av scripten → dispatcha om scorern EN gång enligt
|
|
374
|
+
omdispatch-regeln, med felraderna i prompten. Kvarstår brott: visa dem och
|
|
375
|
+
stanna utan att arkivera svaret som giltigt varv, men släng det inte:
|
|
376
|
+
arkivera som `score-pricing-vN-avvisad.json` (utanför N-räkningen) med
|
|
377
|
+
kontrollens felrader i en runs-rad, så även misslyckade körningar har
|
|
378
|
+
kvitto. En `AVVIKELSE:`-rad visas alltid för användaren.
|
|
379
|
+
6. **Dubbelkörning (driftvakt).** Körs BARA när svaret inte är ett
|
|
380
|
+
stopputfall — stopproutningen nedan går alltid först, en post som ändå
|
|
381
|
+
går till människa ska inte kosta extra körningar. Trigger: poängen är ≥ 1
|
|
382
|
+
(ADR-0098: tröskeln täcker minst det den borttagna klassaxelns
|
|
383
|
+
MEDIUM/LARGE/OFFERT-villkor täckte; poängen multipliceras direkt till
|
|
384
|
+
pris). Dispatcha då `request-scorer` EN gång till,
|
|
385
|
+
samma prompt, ny isolerad körning.
|
|
386
|
+
Kostnaden (en extra körning) läggs medvetet exakt där pengarna står
|
|
387
|
+
på spel — poängen multipliceras direkt till pris och skillens eget
|
|
235
388
|
acceptanstest är att två oberoende körningar ger samma resultat.
|
|
236
|
-
- Kör
|
|
237
|
-
omdispatch-budget (EN
|
|
389
|
+
- Kör hela steg 5 (ankarlösning, sedan kontraktskontroll) på det nya
|
|
390
|
+
svaret först, med egen omdispatch-budget (EN).
|
|
238
391
|
- Jämför sedan deterministiskt:
|
|
239
|
-
`node <skillkatalog>/scripts/compare-classifications.mjs <klass1.json> <klass2.json>`
|
|
240
392
|
`node <skillkatalog>/scripts/compare-scores.mjs <poäng1.json> <poäng2.json>`
|
|
241
|
-
- **
|
|
242
|
-
runs-
|
|
243
|
-
med SAMMA N
|
|
244
|
-
|
|
393
|
+
- **LIKA** → körning 1 gäller: `double_run: "bekräftad"` på dess
|
|
394
|
+
runs-rad. Körning 2-filen arkiveras som `score-pricing-vN-run2.json`
|
|
395
|
+
med SAMMA N och `superseded_by` satt till körning 1-filen.
|
|
396
|
+
`-run2`-filer räknas ALDRIG när nästa N bestäms, och guard och
|
|
245
397
|
`detaljer` läser alltid filen utan suffix.
|
|
246
|
-
- **
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
398
|
+
- **OLIKA** → domen är människans, aldrig maskinens. Arkivera båda
|
|
399
|
+
körningarna (körning 1 utan suffix, körning 2 som `-run2`; på båda
|
|
400
|
+
raderna `double_run: "olika"` med `superseded_by: null`).
|
|
401
|
+
Status `assessed`. Ingen kundtext får gå till
|
|
402
|
+
request-sync medan spärren står (`archive.mjs sparr` är tolken).
|
|
403
|
+
Visa i BLUF-svaret beläggen bakom oenigheten, sida vid sida:
|
|
404
|
+
diffraderna (outcome, score, ankare, konfidens) har ingen
|
|
405
|
+
radkoppling till beläggen, `drivers[]` är en egen lista, så visa
|
|
406
|
+
samtliga `drivers[].citat`/`pastaende` ur båda körningarna
|
|
407
|
+
som stöd för hela utfallet. Det var beläggen som avgjorde domen i
|
|
408
|
+
varje uppmätt äkta oenighet. Hänvisa sedan till `döm <post>` och
|
|
409
|
+
STANNA: ingen omkörning, ingen eskalering, inget val av körning.
|
|
410
|
+
- **LIKA_TOLERANS** (poängskillnad ≤ 0,5 med samma outcome, oavsett
|
|
411
|
+
konfidens, en konfidensskillnad ensam fäller aldrig ett par inom
|
|
412
|
+
toleransen) → paret räknas som bekräftat. Verdiktradens utpekade
|
|
413
|
+
körning (högsta poängen) blir huvudfilen `score-pricing-vN.json`,
|
|
414
|
+
och den andra arkiveras som `-run2` med `superseded_by` satt mot
|
|
415
|
+
huvudfilen, oavsett vilken av dem som var körning 1. Det är
|
|
416
|
+
avsiktligt: båda körningarna har passerat kontraktskontrollen och
|
|
417
|
+
skillnaden ligger inom toleransen. Sätt `double_run: "tolerans"` på
|
|
418
|
+
bägge runs-raderna. Toleransen är en medveten prisregel: högsta
|
|
419
|
+
värdet skyddar marginalen, och ett medelvärde räknas fortfarande
|
|
420
|
+
aldrig fram. Visa toleransraderna i BLUF-svaret.
|
|
421
|
+
- Exit 2 från jämförelsescriptet är ett dispatcherfel (ojämförbara
|
|
258
422
|
körningar) — visa felet och stanna, rapportera aldrig LIKA.
|
|
259
|
-
7. **
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
423
|
+
7. **Arkivera** godkända JSON-svar. Hämta varvets N med
|
|
424
|
+
`node <skillkatalog>/scripts/archive.mjs next-n <katalog> --typ score`,
|
|
425
|
+
skriv filerna (`score-pricing-vN.json`, körning 2
|
|
426
|
+
som `-run2`, avvisade som `-avvisad`), och stämpla VARJE körning med
|
|
427
|
+
`archive.mjs add-run` (flaggor för fil, skill, agent, modell ur
|
|
428
|
+
MODELL-svansraden, effort ur agentdefinitionen, referens-hash via `--ref`
|
|
429
|
+
för skillens referensfil (se runs-kontraktet), double-run-utfall,
|
|
430
|
+
superseded-by, partial-rerun och pairs-with där de gäller). Exempel för
|
|
431
|
+
huvudfilen vid ett bekräftat par:
|
|
432
|
+
`node <skillkatalog>/scripts/archive.mjs add-run <katalog>
|
|
433
|
+
--file score-pricing-v1.json --skill request-score
|
|
434
|
+
--agent request-scorer --model <ur MODELL-svansraden>
|
|
435
|
+
--effort <ur agentdefinitionen> --ref poangskala.md=<hash via
|
|
436
|
+
ref-hash.mjs på request-score/references/poangskala.md>
|
|
437
|
+
--double-run bekräftad`. `--double-run` tar ENDAST de tre
|
|
438
|
+
literalerna `bekräftad`, `olika` eller `tolerans` (scriptet vägrar allt
|
|
439
|
+
annat, flaggnamnet med bindestreck, aldrig `--double_run` med understreck
|
|
440
|
+
som i JSON-fältet). Utelämna flaggan helt när ingen dubbelkörning gjorts.
|
|
441
|
+
`--superseded-by <fil>` och `--partial-rerun` (utan värde) läggs till där
|
|
442
|
+
de gäller, se runs-kontraktet. Stämplingsreglerna
|
|
443
|
+
bor i scriptet och dess tester, inte här. Sätt status via
|
|
444
|
+
`archive.mjs set-status <katalog> priced` (scriptet vägrar vid spärr,
|
|
445
|
+
stopputfall och experiment — se runs-kontraktet)
|
|
446
|
+
eller `assessed`.
|
|
447
|
+
8. **Svara BLUF:** tabell `post · poäng · utfall · konfidens`, en rad
|
|
448
|
+
per avvikelse värd att se (ESKALERA, DELA_UPP,
|
|
276
449
|
INPUT_SAKNAS, AVVIKELSE-rader). JSON:en visas inte i chatten —
|
|
277
450
|
`detaljer <post>` gör det. Skriv-tillbaka till brädan sker via request-sync
|
|
278
451
|
i huvudkonversationen, bara på uttrycklig begäran — och det är den flytten
|
|
279
452
|
som tar posten ✅ Spec ok → ⚖️ Poängsättning redo för granskning enligt
|
|
280
453
|
syncens regler.
|
|
281
454
|
|
|
282
|
-
**Stopputfall routas, aldrig tolkas
|
|
455
|
+
**Stopputfall routas, aldrig tolkas.** Ett stopputfall arkiveras som varvets
|
|
456
|
+
fil (steg 7), statusen blir `assessed`, aldrig `priced`, och posten routas:
|
|
283
457
|
|
|
284
458
|
- `DELA_UPP` → föreslå ny analysrunda per del; delarna blir egna kataloger med
|
|
285
459
|
`split` satt (`part`/`of`), och en del utan tak blir `OVER_SKALAN`, aldrig
|
|
@@ -329,18 +503,431 @@ missta:
|
|
|
329
503
|
- Verben rör Offer status och kommentarer — aldrig Score, Class eller
|
|
330
504
|
beskrivningsfält.
|
|
331
505
|
|
|
506
|
+
## Uppgift: `döm`
|
|
507
|
+
|
|
508
|
+
Människans dom över en post vars dubbelkörning skrev OLIKA. Adressering som
|
|
509
|
+
`godkänn` (radnummer eller gid, aldrig fuzzy). Kräver att spärren står
|
|
510
|
+
(`archive.mjs sparr` exit 1), annars: visa status och stanna.
|
|
511
|
+
|
|
512
|
+
**En variantkatalog (från `utvärdera`) adresseras med sin sökväg direkt,
|
|
513
|
+
aldrig med radnummer eller gid.** Experimentets slug är samma sträng som ett
|
|
514
|
+
vanligt gid skulle vara, så gid-adressering skulle resolva till postkatalogen
|
|
515
|
+
på toppnivå, inte till variantkatalogen under `experiments/<slug>/`.
|
|
516
|
+
`archive.mjs` tar ändå en katalog som argument oavsett var den ligger, så
|
|
517
|
+
sökvägen fungerar identiskt.
|
|
518
|
+
|
|
519
|
+
**En dom på en katalog under `experiments/` skriver aldrig om
|
|
520
|
+
`experiment.json` i sig.** `archive.mjs utslag` och `archive.mjs sparr`
|
|
521
|
+
verkar bara på variantkatalogens egen `state.json`. Statusen i
|
|
522
|
+
`experiment.json` uppdateras inte av `döm` — den uppdateras av `utvärdera`,
|
|
523
|
+
körd igen för samma post, vars återupptagbarhetsregel omvärderar en
|
|
524
|
+
`"väntar på dom"`-variant och gör utfallet synligt för rapporten när den körs
|
|
525
|
+
(se `utvärdera`).
|
|
526
|
+
|
|
527
|
+
1. **Visa underlaget.** Kör jämförelsescriptet på det gällande paret och visa
|
|
528
|
+
varje diffrad med beläggen sida vid sida (som i bedöm steg 6). Ingen
|
|
529
|
+
sammanfattning i stället för beläggen: domen fattas på dem.
|
|
530
|
+
2. **Fråga granskaren** (AskUserQuestion) med tre vägar.
|
|
531
|
+
- **"Körning N gäller"** (N är 1 eller 2, vilken av de två uppmätta
|
|
532
|
+
körningarna som hade rätt): skriv domen via `archive.mjs utslag <katalog> --typ viktning --beslut "<ordagrant>" --beslutad-av <namn> --axel score --n <n> --galler-fil <fil>`.
|
|
533
|
+
(`--axel classification` finns kvar enbart för domar i äldre arkiv
|
|
534
|
+
med en klassaxel, före ADR-0098.)
|
|
535
|
+
`--n` är INTE körningsnumret i rubriken ovan: det är det AKTUELLA
|
|
536
|
+
varvet, avläst ur den senaste pricing-filen
|
|
537
|
+
`score-pricing-v<n>.json` (aldrig `next-n`s utdata, som pekar på
|
|
538
|
+
NÄSTA, ännu okörda varv). `--galler-fil` är den arkiverade fil
|
|
539
|
+
granskaren dömer till
|
|
540
|
+
förmån för: körning 1 → `score-pricing-v<n>.json` utan suffix,
|
|
541
|
+
körning 2 → `score-pricing-v<n>-run2.json`. Efter en beställd
|
|
542
|
+
omkörning (nästa väg) finns TRE arkiverade filer, och
|
|
543
|
+
`--galler-fil` kan peka på VILKEN som helst av dem: omkörningens egen
|
|
544
|
+
fil (version = gällande `n`), eller endera av de två ursprungliga
|
|
545
|
+
körningarnas filer från ett LÄGRE varv, om granskaren dömer att en av
|
|
546
|
+
dem hade rätt hela tiden. Scriptet vägrar bara ett HÖGRE varv än `--n`
|
|
547
|
+
(en dom kan aldrig gälla ett varv som inte fanns när den skrevs) och en
|
|
548
|
+
fil som inte faktiskt arkiverades via `add-run`. Kör `archive.mjs sparr`
|
|
549
|
+
efteråt: exit 0 betyder att spärren är lyft, exit 1 betyder att
|
|
550
|
+
något fortfarande väntar (utskriften namnger vad).
|
|
551
|
+
Inga filer döps om eller skrivs om.
|
|
552
|
+
- **"Beställ omkörning":** EN ny körning, ingen tvångsdubbling: dispatcha
|
|
553
|
+
scorern (ordinarie promptmall och kontraktskedja), arkivera med
|
|
554
|
+
`partial_rerun` och `pairs_with` mot den stående filen. Den nya
|
|
555
|
+
raden väntar precis som originalraden på en dom (`archive.mjs sparr`
|
|
556
|
+
spärrar den ensam, oavsett vad den råkar bära i `double_run`): visa
|
|
557
|
+
scriptdiffen mot BÅDA de stående körningarna och gå till steg 2 igen,
|
|
558
|
+
det är fortfarande granskaren som dömer. Vill granskaren ha två nya
|
|
559
|
+
mätningar beställs två.
|
|
560
|
+
- **"Underlaget är fel":** granskarens beslut appendas i `impact.md` som
|
|
561
|
+
citatblock enligt mallen nedan, assessorn körs om (ny `impact.md`),
|
|
562
|
+
därefter kör `bedöm` ett nytt fullt varv. En körning mot
|
|
563
|
+
gammalt underlag paras aldrig med en mot nytt.
|
|
564
|
+
3. **Kalibreringsnotis.** Är oenigheten äkta (en fråga eller ett ankarval som
|
|
565
|
+
två giltiga körningar läste olika, inte en etikett): skriv `archive.mjs utslag <katalog> --typ kalibrering --beslutad-av <namn> --fraga <id> --lasning1 "<körning 1:s läsning, en mening>" --lasning2 "<körning 2:s läsning>"`.
|
|
566
|
+
Notisen är råmaterial till nästa instruktionsversion (mekanismen bakom
|
|
567
|
+
v0.2 till v0.6) och läses aldrig in i någon prompt. `archive.mjs kalibrering <arkivrot>`
|
|
568
|
+
listar alla.
|
|
569
|
+
|
|
570
|
+
**Granskarutslag skrivs som citat, aldrig som prosa.** När granskarens
|
|
571
|
+
beslut ska in i underlaget, alltså när det ändrar eller preciserar en
|
|
572
|
+
sakuppgift i analysen, eller av annat skäl måste stå i underlaget för
|
|
573
|
+
spårbarhet: appendas det sist i `impact.md` som ett avgränsat block enligt
|
|
574
|
+
mallen nedan, beslutet ordagrant citerat, aldrig omformulerat av
|
|
575
|
+
dispatchern och aldrig invävt i analysens löptext. En fritt formulerad
|
|
576
|
+
utslagsmening läses av nästa körning som sakuppgift och styr om
|
|
577
|
+
bedömningen, det var precis felet i pilotkörningarna, därför alltid mallen,
|
|
578
|
+
aldrig fri prosa. Kräver beslutet en faktisk sakändring i analysen: kör om
|
|
579
|
+
assessorn (ny `impact.md`). Underlaget har i båda fallen ändrats, så
|
|
580
|
+
`bedöm` kör ett nytt fullt varv (se steg 2 ovan, vägen "Underlaget är fel").
|
|
581
|
+
Skriv samtidigt kvittot `archive.mjs utslag <katalog> --typ sakandring --beslut "<ordagrant>" --beslutad-av <namn>`
|
|
582
|
+
i `state.json` (se `granskarutslag` ovan): citatet i `impact.md` är
|
|
583
|
+
underlaget, sakandring-raden är bara revisionsspåret. Ett rent
|
|
584
|
+
viktningsutslag, där granskaren bara konstaterar att en körning hade rätt
|
|
585
|
+
utan att röra någon sakuppgift, hör ALDRIG hemma här: det skrivs i stället
|
|
586
|
+
via `archive.mjs utslag --typ viktning` (se steg 2 ovan, vägen "Körning N
|
|
587
|
+
gäller"), just för att underlaget ska förbli oförändrat. Blocket är internt
|
|
588
|
+
underlag med samma status som Till granskaren-blocket och följer aldrig
|
|
589
|
+
med i kundtext.
|
|
590
|
+
|
|
591
|
+
```
|
|
592
|
+
## Granskarutslag (varv <N>, <YYYY-MM-DD>)
|
|
593
|
+
|
|
594
|
+
> <granskarens beslut, ordagrant>
|
|
595
|
+
|
|
596
|
+
Utslaget gäller endast viktningen mellan körningarna och ändrar inga
|
|
597
|
+
sakuppgifter i analysen ovan.
|
|
598
|
+
```
|
|
599
|
+
|
|
332
600
|
## Uppgift: `detaljer`
|
|
333
601
|
|
|
334
602
|
`detaljer <gid|slug|nr> [steg]` — skriv ut arkiverade filer för posten: utan
|
|
335
603
|
steg en lista över vad som finns, med steg (`spec`, `granskarblock`, `analys`,
|
|
336
|
-
`
|
|
604
|
+
`poäng`, `state`) filens innehåll rått; `klass` läser äldre arkivs
|
|
605
|
+
classification-filer (före ADR-0098). För `klass`/`poäng`: senaste
|
|
337
606
|
`-pricing-vN.json` utan suffix (aldrig `-run2`/`-avvisad`).
|
|
338
607
|
|
|
339
|
-
##
|
|
608
|
+
## Uppgift: `utvärdera`
|
|
609
|
+
|
|
610
|
+
Modellutvärdering: `utvärdera <post…> <modell…>`, med minst en modell. Kör en
|
|
611
|
+
post genom hela flödet en gång per namngiven modell, varje varv med samtliga
|
|
612
|
+
tre agenter (specifiern, assessorn, scorern) tvingade till varvets
|
|
613
|
+
modell, så varje varv mäter en faktisk modellskillnad i stället för brus mellan
|
|
614
|
+
en fast produktionsmix och en enda experimentmodell.
|
|
615
|
+
`default` som modellvärde ger agentdefaults (dagens produktionsblandning) och
|
|
616
|
+
kör utan override; katalognamnet blir då `baseline/`, för alla andra värden
|
|
617
|
+
`<modell>/`. Arkivera all output sida vid sida under experimentytan.
|
|
618
|
+
Uppgiften samlar underlag; människan analyserar. Ingen dom fälls över vilken
|
|
619
|
+
modell som är bäst, och ingen dom simuleras: en OLIKA i något varvs
|
|
620
|
+
dubbelkörning väntar på `döm`, precis som i produktion.
|
|
621
|
+
|
|
622
|
+
**Underkommandon resolvas först.** Är det enda argumentet `sammanställ` eller
|
|
623
|
+
`rapport`, är det underkommandot `utvärdera sammanställ` respektive
|
|
624
|
+
`utvärdera rapport` (se avsnitten nedan). Argumentreglerna nedan gäller aldrig
|
|
625
|
+
de orden; de klassificeras varken som modell eller post-id.
|
|
626
|
+
|
|
627
|
+
**Flaggorna plockas bort först.** `--om`, `--hoppa-över` och `--körning
|
|
628
|
+
<katalog>` (flaggan plus dess värde) lyfts ur argumentlistan INNAN skanningen
|
|
629
|
+
nedan börjar, och räknas varken som modell eller post-id. Utan det steget
|
|
630
|
+
stoppar svepets egen rad, som slutar med `--körning <katalog>`, skanningen
|
|
631
|
+
omedelbart, noll modeller hittas, och kommandot faller på "Minst en modell
|
|
632
|
+
krävs" trots att modellen står där.
|
|
633
|
+
|
|
634
|
+
**Argumenttolkning.** Kvarvarande avslutande argument avgörs höger till vänster
|
|
635
|
+
för att hitta GRÄNSEN mot post-id-listan: ett argument räknas som modell bara
|
|
636
|
+
om det är ett känt agentmodellnamn (`fable`, `opus`, `sonnet`, `haiku`, …) eller
|
|
637
|
+
literalen `default`, allt annat läses som post-id, och skanningen stannar vid
|
|
638
|
+
det första argumentet som inte är ett modellnamn. Ett argument som varken är
|
|
639
|
+
ett känt modellnamn eller ett giltigt gid/slug är ett FEL, aldrig en gissning:
|
|
640
|
+
visa felet och stanna i stället för att chansa på vilken sida av gränsen det
|
|
641
|
+
hör hemma. De modellargument skanningen hittar bildar sedan modellistan i
|
|
642
|
+
DEKLARATIONSORDNING, vänster till höger.
|
|
643
|
+
|
|
644
|
+
**Minst en modell krävs.** Hittar skanningen ingen modell alls är det ett FEL,
|
|
645
|
+
aldrig en default. Ett kommando som kostar timmar och pengar ska säga vilka
|
|
646
|
+
modeller det kör; en tyst standarduppsättning gör att en körning kan starta med
|
|
647
|
+
en annan modell än den som avsågs, och den kostnaden syns först efteråt.
|
|
648
|
+
|
|
649
|
+
**Dubbletter vägras.** Står samma modellvärde två gånger i listan, vägra
|
|
650
|
+
körningen med ett felmeddelande som förklarar varför: två lika värden pekar på
|
|
651
|
+
samma katalognamn och mäter ingen skillnad mot varandra. Vill du köra samma
|
|
652
|
+
modell en gång till, gör det i en egen invokation, då blir det en ny körning
|
|
653
|
+
under samma modell enligt regeln i Experimentytan.
|
|
654
|
+
|
|
655
|
+
**En namngiven modell rör bara sin egen katalog.** Övriga modellers kataloger
|
|
656
|
+
läses inte och skrivs inte. Det är det som gör att en jämförelse kan byggas i
|
|
657
|
+
etapper: `utvärdera <gid> opus sonnet` idag och `utvärdera <gid> fable` en
|
|
658
|
+
vecka senare ger tre modeller under samma post, utan att de första två körs om.
|
|
659
|
+
|
|
660
|
+
**Omkörning frågas fram, den antas aldrig.** Namnger invokationen en modell som
|
|
661
|
+
redan har körningar under sig, stanna INNAN något dyrt startas och fråga om de
|
|
662
|
+
ska köras om. Ställ EN fråga som täcker alla kolliderande modeller, inte en per
|
|
663
|
+
modell. Svaret kan ges i förväg med `--om` (kör om) eller `--hoppa-över` (rör
|
|
664
|
+
dem inte); bär invokationen någon av dem ställs ingen fråga.
|
|
665
|
+
|
|
666
|
+
En omkörning skriver aldrig över den gamla körningen, den blir `k<N+1>`.
|
|
667
|
+
Frågan gäller alltså kostnaden, inte risken att förlora data.
|
|
668
|
+
|
|
669
|
+
1. **Underlag.** Som `speca` steg 1: rått önskemål eller gid — vid gid hämtas
|
|
670
|
+
posten läsande via request-sync i huvudkonversationen, uppgiftens ENDA
|
|
671
|
+
Asana-kontakt. Skapa `experiments/<slug>/` och `experiment.json` med
|
|
672
|
+
ticketreferens, datum och `varianter` i deklarationsordning.
|
|
673
|
+
|
|
674
|
+
Anteckna samtidigt postens `permalink_url` i `experiment.json` när gid-svaret
|
|
675
|
+
bär det. Det kommer ur samma läsande hämtning som redan görs, så steget får
|
|
676
|
+
ingen ny Asana-kontakt. Saknas fältet i svaret skrivs det inte, och rapporten
|
|
677
|
+
visar då gid som ren text: Asanas permalänk bär ett workspace-gid som inte
|
|
678
|
+
finns på experimentytan, så en konstruerad URL vore en gissning.
|
|
679
|
+
|
|
680
|
+
**`experiment.json` skrivs läs-modifiera-skriv, aldrig från noll.** Saknas
|
|
681
|
+
filen skapas den. Finns den redan läses den in FÖRST och uppdateras sedan:
|
|
682
|
+
`varianter` slås ihop som UNION med bevarad deklarationsordning, de
|
|
683
|
+
befintliga namnen först och invokationens nya namn efter, och en befintlig
|
|
684
|
+
körnings `status` skrivs aldrig över av en process som inte äger just den
|
|
685
|
+
körningen. En headless-process med en enmodellslista rör alltså bara sin
|
|
686
|
+
egen modell. Utan regeln raderar `fable`-körningen en vecka senare `opus`
|
|
687
|
+
och `sonnet` ur filen, och eftersom det är den här filen
|
|
688
|
+
återupptagningsregeln läser (se Återupptagbart nedan) slutar ett återupptaget
|
|
689
|
+
svep känna igen färdiga körningar och betalar om för dem. Skrivningen ska
|
|
690
|
+
vara ATOMISK: skriv till en temporärfil i samma katalog och byt namn.
|
|
691
|
+
`experiment.json` är den enda filen på experimentytan som delas mellan
|
|
692
|
+
samtidiga processer utan den låsning `archive.mjs ny-korning` ger
|
|
693
|
+
körningskatalogerna, så samtidighetsdisciplinen måste stå här i stället.
|
|
694
|
+
|
|
695
|
+
2. **Källmanifest EN gång.** Bygg manifestet som i `speca` steg 2 och
|
|
696
|
+
återanvänd det byteidentiskt i ALLA varv. Anteckna manifest-hash i
|
|
697
|
+
`experiment.json` (`ref-hash.mjs` på manifesttexten). Enda avsedda
|
|
698
|
+
skillnaden mellan varven är modellen.
|
|
699
|
+
3. **Eskaleringsvalet görs en gång** enligt `speca`:s regler och gäller alla
|
|
700
|
+
varv, även eskaleringsvalet är en del av det som hålls konstant.
|
|
701
|
+
Triggar valet: agenten blir `request-specifier-eskalerad` i stället för
|
|
702
|
+
`request-specifier`, likadant i alla varv. Modell-overriden i steg 4
|
|
703
|
+
gäller ändå den eskalerade agenten precis som de två andra: dess egen
|
|
704
|
+
pinnade modell, den som enligt agentdefinitionen ÄR eskaleringen, skrivs
|
|
705
|
+
över av varvets modell. Eskaleringsmekanismen kollapsar alltså medvetet
|
|
706
|
+
under override, det är avsett, inte en lucka: `utvärdera` mäter en ren
|
|
707
|
+
modellskillnad över alla tre rollerna och testar aldrig
|
|
708
|
+
eskaleringsbeslutet i sig.
|
|
709
|
+
4. **Ett varv per modell i listan**, sekventiellt, i deklarationsordning.
|
|
710
|
+
Varje varv är EN egen headless-process, och det är det som ger mätningen
|
|
711
|
+
gratis. Ansvaret delas, eftersom en process aldrig kan känna sin egen
|
|
712
|
+
slutkostnad:
|
|
713
|
+
|
|
714
|
+
**Startaren** (huvudkonversationen, eller svepets loop) gör per modell:
|
|
715
|
+
allokerar körningskatalogen med `archive.mjs ny-korning`, startar
|
|
716
|
+
`claude -p --model sonnet --output-format json` med katalogen som explicit
|
|
717
|
+
argument, väntar in processen, och skriver JSON-svaret rått till
|
|
718
|
+
`<modell>/k<N>/korning.json`. Rapporten läser sedan `total_cost_usd`,
|
|
719
|
+
`usage.input_tokens`, `usage.output_tokens`,
|
|
720
|
+
`usage.cache_read_input_tokens`, `usage.cache_creation_input_tokens` och
|
|
721
|
+
`subagent_stats.spawned` ur den filen.
|
|
340
722
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
723
|
+
**Startaren tar tiden runt processen** och skriver `<modell>/k<N>/matning.json`
|
|
724
|
+
med `startad`, `avslutad` (båda ISO 8601) och `wall_ms` (differensen).
|
|
725
|
+
Filen skrivs ÄVEN när processen faller: en kraschad körning har en klocktid,
|
|
726
|
+
och den är ofta det intressantaste talet i tabellen. Rapporten läser
|
|
727
|
+
väggtiden därifrån, aldrig ur `korning.json`. Skälet är detsamma som för
|
|
728
|
+
kostnaden: en process kan inte känna sin egen klocktid när arbetet ligger i
|
|
729
|
+
bakgrundssubagenter, och svarets `duration_ms` räknar inte in väntan på dem.
|
|
730
|
+
`korning.json` förblir headless-svaret rått, därav den egna filen.
|
|
731
|
+
|
|
732
|
+
Startaren stämplar samtidigt körningens `state.json` med `proveniens`:
|
|
733
|
+
|
|
734
|
+
```
|
|
735
|
+
node <skillkatalog>/scripts/archive.mjs proveniens <modell>/k<N> \
|
|
736
|
+
--modell <varvets modellvärde> --konto <vilket Claude-konto som körde> \
|
|
737
|
+
--underlag <sökväg till källmanifestet>
|
|
738
|
+
```
|
|
739
|
+
|
|
740
|
+
Kommandot räknar själv `skill_sha256` (över `SKILL.md` plus de fyra
|
|
741
|
+
agentdefinitionerna) och `underlag_sha256`, läser `korning.json` och
|
|
742
|
+
antecknar `fakturerade_modeller` (den kanoniserade nyckelmängden ur
|
|
743
|
+
`modelUsage`, suffix som `[1m]` strippade — ADR-0099), och stämplar även varje
|
|
744
|
+
`del-N/`. Utan den stämpeln går det inte att avgöra
|
|
745
|
+
vad som skilde `k1` från `k2`, och en jämförelse över tid blir en
|
|
746
|
+
gissning. Anropet står här som ett
|
|
747
|
+
kommando och inte som en beskrivning med flit: ett steg som ålägger
|
|
748
|
+
startaren en skrivning utan att peka ut vem som utför den är en skrivning
|
|
749
|
+
som inte blir av, och den syns först som tomma celler långt senare.
|
|
750
|
+
Kör därför proveniens-stämpeln EFTER att `korning.json` skrivits, aldrig
|
|
751
|
+
före — annars saknar stämpeln faktureringsdatan.
|
|
752
|
+
|
|
753
|
+
**Modellverifiering görs av startaren mot faktureringen (ADR-0099),
|
|
754
|
+
aldrig mot svansraden ensam.** När processen är klar: jämför
|
|
755
|
+
`fakturerade_modeller` mot varvets begärda modell plus orkestratorns
|
|
756
|
+
(sonnet). En modellnyckel som varken är varvets modell eller
|
|
757
|
+
orkestratorns är en faktisk MODELL-avvikelse → körningen blir
|
|
758
|
+
`"ofärdig"`. En MODELL-svansrad som säger något annat än vad
|
|
759
|
+
`modelUsage` visar är en RAPPORTERINGSAVVIKELSE: den visas i rapporten
|
|
760
|
+
och står kvar i `runs[]` (raden bär agentens uppgift i
|
|
761
|
+
`model.uppgiven`), men den fäller ALDRIG ensam körningen — modeller är
|
|
762
|
+
opålitliga källor om sin egen identitet, och att kasta en korrekt
|
|
763
|
+
körning på en felskriven svansrad betalar om ett riktigt resultat.
|
|
764
|
+
Modellvärdet `default` kör agenternas egna defaults och får lagligt
|
|
765
|
+
producera flera modellnycklar: ingen mängdjämförelse görs där.
|
|
766
|
+
|
|
767
|
+
**Den inre processen** känns igen på invokationen, aldrig på gissning: bär
|
|
768
|
+
den `--körning`, är du den inre processen. Allokera då ingen katalog, starta
|
|
769
|
+
ingen ny process, och kör stegen direkt mot den anvisade katalogen. Utan det
|
|
770
|
+
stoppvillkoret läser den inre processen samma uppgift som startaren, startar
|
|
771
|
+
ett varv till och dubblar notan.
|
|
772
|
+
|
|
773
|
+
Den inre processen kör speca-stegen (dispatch, kontraktskontroll,
|
|
774
|
+
arkivering) och därefter bedöm-stegen (analys, poäng,
|
|
775
|
+
ankarlösning, dubbelkörning enligt bedöm) mot den anvisade katalogen, utan
|
|
776
|
+
godkännandegrind, och rör ingenting utanför den. Är modellen `default`
|
|
777
|
+
används ordinarie promptmallar och agenternas defaults, ingen override. Är
|
|
778
|
+
den ett modellnamn får varje Agent-anrop modell-override till den på ALLA
|
|
779
|
+
tre agenter; agentdefinitionerna röres aldrig, effort tas ur definitionen
|
|
780
|
+
som vanligt. Overriden verifieras av STARTAREN mot `modelUsage` (se
|
|
781
|
+
modellverifieringen ovan) — svansraden arkiveras men avgör aldrig ensam.
|
|
782
|
+
`approval` förblir `null`, `state.json`
|
|
783
|
+
får `"experiment": true`. `REQUEST_ID` och `--expect-id` använder alltid
|
|
784
|
+
ticketens gid/slug, aldrig katalogens namn.
|
|
785
|
+
|
|
786
|
+
Orkestratorn pinnas till sonnet i ALLA körningar. Dess kostnad blir då en
|
|
787
|
+
konstant som går att räkna bort, och `modelUsage` i JSON-svaret skiljer den
|
|
788
|
+
från agenternas kostnad utan extra arbete.
|
|
789
|
+
|
|
790
|
+
Subagentdöd, kontraktsbrott (kvarstående BROTT efter omdispatch) eller
|
|
791
|
+
en faktisk MODELL-avvikelse (obegärd nyckel i `modelUsage`, aldrig en
|
|
792
|
+
ensam svansradsavvikelse), i vilket steg det än inträffar, sätter
|
|
793
|
+
körningens `status` till `"ofärdig"` i `experiment.json`.
|
|
794
|
+
|
|
795
|
+
5. **DELA_UPP körs autonomt.** Ett DELA_UPP-utfall följer bedöms ordinarie
|
|
796
|
+
delningsregler men utan paus för granskare: delkataloger
|
|
797
|
+
`<modell>/k<N>/del-1/ … del-N/` med `split` satt, förälderns `spec.md` +
|
|
798
|
+
`granskarblock.md` kopierade in, ny analys + poäng per del.
|
|
799
|
+
En del utan tak blir `OVER_SKALAN` och delas aldrig vidare. Övriga
|
|
800
|
+
stopputfall (`TILLBAKA_TILL_SPEC`, `KONCEPT`, `DIAGNOS`, `ESKALERA`,
|
|
801
|
+
`INPUT_SAKNAS`) kräver människa eller kund: arkivera utfallet, avbryt det
|
|
802
|
+
varvet, gör det synligt i rapporten när den körs, och övriga körningar i
|
|
803
|
+
listan fortsätter oberoende.
|
|
804
|
+
|
|
805
|
+
**OLIKA väntar på dom.** Skriver dubbelkörningen OLIKA i ett varv:
|
|
806
|
+
arkivera enligt bedöms regler (spärren står), sätt körningens status till
|
|
807
|
+
`"väntar på dom"` i `experiment.json`, synligt i rapporten när den körs.
|
|
808
|
+
Domen är människans även i experimentet: `döm` körs mot körningskatalogen
|
|
809
|
+
när granskaren vill (adresserad via sin sökväg, se `döm`), och ingen dom
|
|
810
|
+
simuleras av uppgiften. Domen i sig skriver inte om `experiment.json`,
|
|
811
|
+
det gör `utvärdera` självt, nästa gång det körs för samma post (se
|
|
812
|
+
Återupptagbart i avsnittet Batch nedan för hur och när statusen går
|
|
813
|
+
till `"klar"` och rapporten kan visa utfallet). Övriga körningar i listan
|
|
814
|
+
fortsätter oberoende oavsett när, eller om, domen fälls.
|
|
815
|
+
|
|
816
|
+
6. **Rapport.** BLUF i chatten: klart eller ofärdigt per körning, stopputfall,
|
|
817
|
+
och sökvägen till `experiments/<slug>/`. Nämn att `utvärdera rapport` finns
|
|
818
|
+
när underlaget ska läsas sida vid sida. Ingen skrivning mot Asana.
|
|
819
|
+
|
|
820
|
+
### Batch: flera poster
|
|
821
|
+
|
|
822
|
+
`utvärdera <post1> <post2> … <modell…>` kör varje ticket och modell i en EGEN
|
|
823
|
+
headless-process, sekventiellt:
|
|
824
|
+
|
|
825
|
+
```
|
|
826
|
+
claude -p --model sonnet --output-format json "/request utvärdera <gid> <modell> --hoppa-över --körning <katalog>"
|
|
827
|
+
```
|
|
828
|
+
|
|
829
|
+
Orkestratorn är huvudloopens modell och pinnas till sonnet i headless:
|
|
830
|
+
agenternas modeller styrs av definition plus override och verifieras av
|
|
831
|
+
startaren mot `modelUsage` i `korning.json` (ADR-0099) —
|
|
832
|
+
aldrig av huvudloopens val, och aldrig av svansraden ensam.
|
|
833
|
+
|
|
834
|
+
**Raden bär ALLTID `--om` eller `--hoppa-över`, och väljer `--hoppa-över`.**
|
|
835
|
+
Det är inte en stilregel utan det som gör svepet möjligt: en `claude -p`-process
|
|
836
|
+
kan inte svara på en fråga, så en rad utan flagga skulle hänga eller gissa.
|
|
837
|
+
`--hoppa-över` är dessutom precis återupptagningens semantik, ett avbrutet svep
|
|
838
|
+
som startas om plockar upp där det stannade i stället för att betala om för
|
|
839
|
+
allt färdigt.
|
|
840
|
+
|
|
841
|
+
`--körning <katalog>` pekar ut den körningskatalog som `archive.mjs ny-korning`
|
|
842
|
+
redan allokerat åt den ticketen och modellen. Den inre processen arkiverar
|
|
843
|
+
bara dit, aldrig någon annanstans.
|
|
844
|
+
|
|
845
|
+
Svepets loop är startaren och har startarens hela ansvar per rad: den tar tiden
|
|
846
|
+
runt `claude -p`-anropet och skriver `matning.json`, och den kör
|
|
847
|
+
`archive.mjs proveniens` mot körningskatalogen när processen är klar.
|
|
848
|
+
|
|
849
|
+
- **En ticket = ett färskt kontextfönster.** Allt tillstånd bor i arkivet på
|
|
850
|
+
disk; huvudsessionen samlar bara exitstatus och en radssammanfattning per
|
|
851
|
+
ticket. `/clear` mellan tickets behövs inte — processgränsen är
|
|
852
|
+
motsvarigheten. Headless-körningen förutsätter att uppgiften kan köra utan
|
|
853
|
+
interaktiva permission-frågor, vilket håller: den läser repot och skriver
|
|
854
|
+
enbart under `.haus/requests/` — plus EN läsande Asana-hämtning per ticket
|
|
855
|
+
(steg 1), så MCP-behörigheten för läsning måste täcka headless-körning.
|
|
856
|
+
- **Kör vidare vid fel.** En ticket vars gid inte går att hämta eller vars
|
|
857
|
+
process kraschar noteras i sammanfattningen; resten av listan fortsätter.
|
|
858
|
+
- **Återupptagbart:** innan en körning startas kontrolleras arkivet, styrt av
|
|
859
|
+
körningens `status` i `experiment.json`. `"klar"` och `"stopp"` hoppas
|
|
860
|
+
över med en notis. `"ofärdig"` är avbruten data, inget resultat värt att
|
|
861
|
+
skydda: den utlöser aldrig omkörningsfrågan, utan körs om automatiskt som
|
|
862
|
+
en ny `k<N+1>` under samma modell. Den gamla ofärdiga körningen skrivs
|
|
863
|
+
ändå aldrig över, den står kvar som historik över vad som gick fel.
|
|
864
|
+
`"väntar på dom"` OMVÄRDERAS i stället för att hoppas över, det är den
|
|
865
|
+
enda platsen som är aktören för den statusen: kör `archive.mjs sparr` på
|
|
866
|
+
körningskatalogen. Exit 0 betyder att domen är fälld: sätt körningens
|
|
867
|
+
status till `"klar"` och fortsätt där den stannade (rapporten kan köras
|
|
868
|
+
separat när alla körningar för posten är klara). Exit 1 betyder att
|
|
869
|
+
den fortfarande väntar: notera det och gå vidare till nästa ticket.
|
|
870
|
+
`döm` fäller domen men rör aldrig `experiment.json` (se `döm`), det är
|
|
871
|
+
bara genom att `utvärdera` körs igen för samma post som statusen
|
|
872
|
+
uppdateras. Omkörningsfrågan (se `utvärdera` ovan) gäller alltså bara
|
|
873
|
+
`"klar"`-körningar: det är resultat värda att skydda mot ett fingerfel,
|
|
874
|
+
en ofärdig körning har inget att skydda. Körningar är billiga relativt
|
|
875
|
+
risken att lappa ihop halva resultat. Ett svep över många tickets kan
|
|
876
|
+
därmed fortsätta i en senare session utan onödiga omkörningar.
|
|
877
|
+
|
|
878
|
+
### Sammanställning
|
|
879
|
+
|
|
880
|
+
`utvärdera sammanställ` läser alla `experiments/*/` och skriver
|
|
881
|
+
`experiments/sammanstallning.md`: tabell per ticket med en rad per modell som
|
|
882
|
+
bär poäng, delnings- och stopputfall, plus avvikelsemarkering där
|
|
883
|
+
modellerna skiljer sig. Modellens rad tas ur dess GÄLLANDE körning, den högsta
|
|
884
|
+
`k<N>` vars status i `experiment.json` är `"klar"`. En modell utan klar körning
|
|
885
|
+
representeras av sin senaste `k<N>` och märks `ofullständig` tillsammans med
|
|
886
|
+
den körningens status. Halvfärdiga kataloger märks likadant, aldrig tyst
|
|
887
|
+
utelämnade. Bara läsning — inga agentdispatcher, inga Asana-anrop.
|
|
888
|
+
|
|
889
|
+
### Rapport
|
|
890
|
+
|
|
891
|
+
`utvärdera rapport [--ut <fil>]` renderar en HTML-rapport över experimentytan
|
|
892
|
+
med `scripts/report.mjs`. Rapporten täcker ALLTID hela ytan; något postfilter
|
|
893
|
+
finns inte, menyn i rapporten är där läsaren väljer post. Utan `--ut` skrivs
|
|
894
|
+
HTML på stdout, annars till filen. Publicera den som artefakt när den ska
|
|
895
|
+
läsas.
|
|
896
|
+
|
|
897
|
+
**Rapporten skrivs ALDRIG automatiskt.** Ingen körning genererar den när den
|
|
898
|
+
blir klar. Den kostar nästan ingenting att regenerera, så det finns ingen
|
|
899
|
+
anledning att skriva den på spekulation, och en fil som ingen bett om är en fil
|
|
900
|
+
ingen litar på.
|
|
901
|
+
|
|
902
|
+
Rapporten är ren läsning: inga agentdispatcher, inga Asana-anrop, inga
|
|
903
|
+
skrivningar i arkivet utöver utdatafilen.
|
|
904
|
+
|
|
905
|
+
Vad den visar: en meny över poster med ticketens titel, dess katalogslug och
|
|
906
|
+
vilka modeller posten har, och per vald post en kolumn per körning. Varje delpost ur
|
|
907
|
+
ett DELA_UPP-utfall är en egen kolumn efter sin körning (`opus / k1 / del-1`),
|
|
908
|
+
eftersom det är där utfallen bor när en post delat sig. Sektionerna är fältvisa,
|
|
909
|
+
samma fält på samma rad tvärs kolumnerna: utfall, poängens inringning med
|
|
910
|
+
golv, tak, steg och drivers,
|
|
911
|
+
specens fyra fält, samt `impact.md` och `granskarblock.md` hopfällda per
|
|
912
|
+
körning. Äldre körningar med klassningsfiler (före ADR-0098) får dessutom
|
|
913
|
+
sin Klassning-sektion renderad som förut — kalibreringshistoriken kastas inte.
|
|
914
|
+
Sist står kostnaden (USD, tokens, väggtid, dispatcher) och proveniensen.
|
|
915
|
+
En delkolumn saknar egen mätning och säger `ingår i k<N>`, aldrig omätt.
|
|
916
|
+
Matrisen är ojämn med flit: en post kan ha två modeller och en annan tre,
|
|
917
|
+
eftersom en dyrare modell läggs till bara där de billigare inte räckte.
|
|
918
|
+
|
|
919
|
+
Vad den ALDRIG gör: rangordnar modeller, rekommenderar en nivå, räknar aggregat
|
|
920
|
+
tvärs poster med olika modelluppsättning, eller uttalar sig om vilket utfall
|
|
921
|
+
som var korrekt. Bedömningen av vad som är ett acceptabelt utfall är
|
|
922
|
+
människans, gjord på erfarenhet av systemet. Rapporten visar spridningen.
|
|
923
|
+
|
|
924
|
+
## Mekaniska script: `scripts/`
|
|
925
|
+
|
|
926
|
+
Nio deterministiska script bor i katalogen: de fem kontrollerna nedan,
|
|
927
|
+
`archive.mjs` som äger arkivets kataloger och spärrar, `report.mjs` som
|
|
928
|
+
renderar modellrapporten (se `utvärdera rapport`), `lib.mjs` med de delade
|
|
929
|
+
byggstenarna och `ref-hash.mjs` för stabil hashning. Kontrollerna ersätter
|
|
930
|
+
modellkörningar där kontrollen är ren form,
|
|
344
931
|
billigare, snabbare och utan omdömesglidning. Varje script bär sha256 för de
|
|
345
932
|
referensfiler vars regler det speglar och VARNAR när en katalogbump ändrat dem
|
|
346
933
|
(kontraktsdrift ska upptäckas av en check, inte av en kund):
|
|
@@ -349,28 +936,39 @@ referensfiler vars regler det speglar och VARNAR när en katalogbump ändrat dem
|
|
|
349
936
|
dispatcher: rubriker, exakt ett specblock, 2–5 punkter, förbjuden vokabulär,
|
|
350
937
|
granskarblocksrader, state.json-fält. Skiljer på BRISTER (exit 1, stoppar)
|
|
351
938
|
och VARNING (heuristik — visas, stoppar inte).
|
|
939
|
+
- `scripts/resolve-anchors.mjs <run.json> <spec.md> [impact.md]` — löser
|
|
940
|
+
beläggsankare (`belagg_ankare`/`ankare`) till ordagranna källblock, körs
|
|
941
|
+
FÖRE contract-check. Exit 0 = allt löst (eller inga ankare i filen), 1 =
|
|
942
|
+
minst ett OLÖST/FLERTYDIG ankare (kontraktsbrott, mekanisk omdispatch),
|
|
943
|
+
2 = användningsfel.
|
|
352
944
|
- `scripts/contract-check.mjs <run.json> <spec.md> [impact.md] [--expect-id <id>]`
|
|
353
|
-
— kontraktskontroll av
|
|
945
|
+
— kontraktskontroll av score-JSON EFTER körning: enums,
|
|
354
946
|
konfidensintervall, poängupplösning, inringningens närvaro (även per
|
|
355
947
|
alternativ; under-A1-fallet med floor null och tak A1 är giltigt), belägg/
|
|
356
948
|
driver-citat som ordagranna substrängar av underlaget, protokollterm-
|
|
357
949
|
svartlista i kundtextfält, sluten kuvertnyckellista, request_id mot katalogen.
|
|
358
|
-
INPUT_SAKNAS kräver saknas-lista i stället för frågerader.
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
950
|
+
INPUT_SAKNAS kräver saknas-lista i stället för frågerader. Ett olöst ankare
|
|
951
|
+
(belägg saknas trots `belagg_ankare`, eller `ankare` utan `citat`) är
|
|
952
|
+
dispatcherns fel, inte agentens: exit 2 med hänvisning till resolve-anchors.mjs.
|
|
953
|
+
- `scripts/check-lasta.mjs "<LÄSTA-innehåll>" <spec.md> <impact.md>` —
|
|
954
|
+
kontrollerar scorerns läs-scope: LÄSTA-raden ska bära underlagens två
|
|
955
|
+
sökvägar och får därutöver bara bära filer under skillens egen katalog.
|
|
956
|
+
Exit 0 = ok, 1 = kontraktsbrott (BROTT-rader), 2 = användningsfel.
|
|
957
|
+
- `scripts/compare-scores.mjs <a.json> <b.json>` — deterministisk
|
|
958
|
+
dubbelkörningsdiff: outcome,
|
|
959
|
+
score, confidence, golv- och takankare. Aldrig prosa. Skriver `LIKA`,
|
|
960
|
+
`LIKA_TOLERANS` (poängskillnad ≤ 0,5 med samma outcome, oavsett confidence,
|
|
961
|
+
och ankarband som överlappar eller angränsar; exit 0, verdiktraden pekar ut
|
|
962
|
+
körningen med högst poäng) eller `OLIKA` + diffrader; exit 0/1, exit 2 =
|
|
963
|
+
ojämförbara körningar (dispatcherfel, aldrig LIKA). Scriptet kräver mode
|
|
964
|
+
`pricing`; guard-jämförelser är en medveten utbyggnad i guard-steget.
|
|
367
965
|
|
|
368
966
|
Kontrollerna bedömer aldrig innehåll och returnerar aldrig protokollutfall —
|
|
369
967
|
en post som passerar kan fortfarande stoppas av protokollen själva, och det är
|
|
370
968
|
deras jobb. Vid script-fel (exit 2 eller krasch): visa felet och stanna, kör
|
|
371
969
|
aldrig vidare som om kontrollen passerat.
|
|
372
970
|
|
|
373
|
-
## Dispatch-kontrakt (gäller alla
|
|
971
|
+
## Dispatch-kontrakt (gäller alla tre agenterna)
|
|
374
972
|
|
|
375
973
|
- Prompten är självbärande: agenten ser inte den här konversationen.
|
|
376
974
|
- **Promptmallar, etiketterna ordagrant:**
|
|
@@ -400,31 +998,32 @@ aldrig vidare som om kontrollen passerat.
|
|
|
400
998
|
<granskarblock.md bytetroget>
|
|
401
999
|
```
|
|
402
1000
|
|
|
403
|
-
`request-
|
|
1001
|
+
`request-scorer` (underlag per sökväg, ADR-0099 — aldrig inklistrat):
|
|
404
1002
|
|
|
405
1003
|
```
|
|
406
1004
|
REQUEST_ID: <gid eller slug>
|
|
407
1005
|
MODE: <pricing|guard>
|
|
408
1006
|
DELPOST: <nej | ja, del N av M>
|
|
409
1007
|
|
|
410
|
-
SPEC:
|
|
411
|
-
<
|
|
412
|
-
|
|
413
|
-
PÅVERKANSANALYS:
|
|
414
|
-
<impact.md bytetroget>
|
|
1008
|
+
SPEC: <absolut sökväg till spec.md>
|
|
1009
|
+
PÅVERKANSANALYS: <absolut sökväg till impact.md>
|
|
415
1010
|
```
|
|
416
1011
|
|
|
417
|
-
(guard-läge lägger till `FULLPLAN:` och `
|
|
418
|
-
|
|
1012
|
+
(guard-läge lägger till `FULLPLAN:` och `TIDIGARE_POANG:` —
|
|
1013
|
+
guard-kommandot kommer i ett senare steg.)
|
|
419
1014
|
|
|
420
1015
|
- **Svansrader efter huvudinnehållet**, i denna ordning: `MODELL: <modell-id>`
|
|
421
1016
|
(alla agenter), `LÄSTA: <kommaseparerade absoluta sökvägar eller "inga">`
|
|
422
|
-
(endast
|
|
1017
|
+
(endast scorern — dess Read är promptbegränsad, raden gör regeln
|
|
423
1018
|
granskbar), `AVVIKELSE: <text>` (endast om något i prompten bröt mot agentens
|
|
424
1019
|
regler, t.ex. en prislista i underlaget). Svansraderna strippas före varje
|
|
425
1020
|
maskinell kontroll och före arkivering; MODELL antecknas i runs-raden,
|
|
426
|
-
|
|
427
|
-
|
|
1021
|
+
AVVIKELSE visas alltid för användaren. LÄSTA kontrolleras MEKANISKT av
|
|
1022
|
+
`scripts/check-lasta.mjs` (ADR-0099): raden ska bära underlagens två
|
|
1023
|
+
utpekade sökvägar (båda obligatoriska) och får därutöver bara bära filer
|
|
1024
|
+
under skillens egen katalog (referensfilen) — allt annat är ett
|
|
1025
|
+
kontraktsbrott och behandlas som BROTT i bedöm steg 5 (omdispatch EN
|
|
1026
|
+
gång, sedan stopp), aldrig bara en notis.
|
|
428
1027
|
- Agentens svar i övrigt är rådata enligt skillens kontrakt (prosa-dokument
|
|
429
1028
|
eller JSON), ingen kommentar runt om.
|
|
430
1029
|
- **Omdispatch (max EN per agent och varv):** skicka HELA ursprungsprompten
|
|
@@ -434,6 +1033,11 @@ aldrig vidare som om kontrollen passerat.
|
|
|
434
1033
|
<felraderna från kontrollen, citerade ordagrant>
|
|
435
1034
|
```
|
|
436
1035
|
En ny subagent minns inget — enbart felrader utan underlag är obrukbart.
|
|
1036
|
+
**Omtaget bokförs alltid (ADR-0099):** det förkastade försöket arkiveras
|
|
1037
|
+
med `-avvisad`-suffix (prissättning: `<typ>-pricing-vN-avvisad.json`;
|
|
1038
|
+
textsteg: `spec-avvisad-<datum>.md` / `impact-avvisad-<datum>.md`) och får
|
|
1039
|
+
en egen runs-rad med kontrollens felrader — två körningar av samma steg
|
|
1040
|
+
utan spår av varför är precis den lucka kvittot stänger.
|
|
437
1041
|
|
|
438
1042
|
## Använd inte när
|
|
439
1043
|
|
|
@@ -442,5 +1046,5 @@ aldrig vidare som om kontrollen passerat.
|
|
|
442
1046
|
- Frågan gäller Asana-uppsättning ("koppla repot") — det är request-sync:s
|
|
443
1047
|
uppsättningsflöde, kör den direkt.
|
|
444
1048
|
- Guard-läget ("kör guarden", före första kodrad) — körs tills vidare via
|
|
445
|
-
request-
|
|
1049
|
+
request-score direkt; ett `guard`-kommando kommer i ett
|
|
446
1050
|
senare steg.
|