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