@haus-tech/haus-workflow 5.0.0 → 5.1.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 +13 -0
- package/dist/cli.js +913 -751
- package/library/catalog/manifest.json +67 -61
- package/library/global/agents/request-assessor.md +10 -2
- package/library/global/agents/request-specifier-eskalerad.md +8 -0
- package/library/global/agents/request-specifier.md +8 -3
- package/library/global/skills/request/SKILL.md +590 -227
- package/library/global/skills/request/scripts/archive.mjs +736 -59
- package/library/global/skills/request/scripts/compare-scores.mjs +119 -13
- package/library/global/skills/request/scripts/contract-check.mjs +268 -40
- package/library/global/skills/request/scripts/kontroll.mjs +622 -0
- package/library/global/skills/request/scripts/korning.mjs +1502 -0
- package/library/global/skills/request/scripts/lib.mjs +477 -5
- package/library/global/skills/request/scripts/precheck.mjs +132 -5
- package/library/global/skills/request/scripts/report.mjs +85 -14
- package/library/global/skills/request/scripts/svep.mjs +640 -0
- package/library/global/skills/request-assess-impact/SKILL.md +45 -4
- package/library/global/skills/request-score/SKILL.md +51 -11
- package/library/global/skills/request-score/references/poangskala.md +3 -0
- package/library/global/skills/request-sync/SKILL.md +3 -3
- package/library/global/skills/request-write-spec/SKILL.md +9 -4
- package/library/global/skills/request-write-spec/references/specformat.md +48 -0
- package/package.json +1 -1
|
@@ -65,7 +65,7 @@ respektive skill. Här bor bara routing, kontextbärande, arkivet och dispatchen
|
|
|
65
65
|
- **Experimentdata når aldrig Asana.** `utvärdera` skriver aldrig via
|
|
66
66
|
request-sync; dess enda Asana-kontakt är läsande hämtning av önskemålet i
|
|
67
67
|
huvudkonversationen. `experiments/`-trädet är inte postkataloger: sync,
|
|
68
|
-
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
|
|
69
69
|
och rör aldrig `experiments/`.
|
|
70
70
|
- **Maskinen kör om enbart vid scriptbevisat kontraktsbrott.** Omdispatch
|
|
71
71
|
(budget EN per agent) svarar på ett fel som precheck, resolve-anchors eller
|
|
@@ -74,7 +74,7 @@ respektive skill. Här bor bara routing, kontextbärande, arkivet och dispatchen
|
|
|
74
74
|
maskinkörningar producerar fler röster, aldrig mer sanning. Ingen ny
|
|
75
75
|
omkörningsmekanism får läggas till som bryter mot detta.
|
|
76
76
|
|
|
77
|
-
## Arkivet: `.haus/requests/`
|
|
77
|
+
## Arkivet: `.haus-workflow/requests/`
|
|
78
78
|
|
|
79
79
|
Orkestreringens kuvert. De haus-hanterade request-skillsen känner inte till det;
|
|
80
80
|
den här skillen (och agenterna via sina prompter) underhåller det.
|
|
@@ -84,10 +84,10 @@ samma önskemål) blir flera kataloger — poängen sätts per post, så en kata
|
|
|
84
84
|
med flera specar går inte att bedöma.
|
|
85
85
|
|
|
86
86
|
```
|
|
87
|
-
<repo-rot>/.haus/requests/<gid-eller-slug>/
|
|
87
|
+
<repo-rot>/.haus-workflow/requests/<gid-eller-slug>/
|
|
88
88
|
├── spec.md EN spec, bytetrogen — det granskaren godkänner
|
|
89
|
-
├── granskarblock.md "## Till granskaren" (bunt:
|
|
90
|
-
│
|
|
89
|
+
├── granskarblock.md "## Till granskaren" (bunt: delens eget
|
|
90
|
+
│ block, aldrig ett kopierat, ADR-0118)
|
|
91
91
|
├── impact.md påverkansanalysen, ordagrann inkl. sitt
|
|
92
92
|
│ Till granskaren-block
|
|
93
93
|
├── score-pricing-vN.json nytt varv = ny fil, skriv aldrig över
|
|
@@ -109,10 +109,15 @@ omdispatch-regeln i dispatch-kontraktet.
|
|
|
109
109
|
- Katalognamn: Asana-gid när posten finns på brädan, annars en kebab-slug av
|
|
110
110
|
spec-rubriken. Bunt utan gid: `<slug>-1`, `<slug>-2`, … När gid myntas senare:
|
|
111
111
|
döp om katalogen till gid och notera sluggen i `state.json.former_slug`.
|
|
112
|
-
- **
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
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.
|
|
116
121
|
|
|
117
122
|
### `state.json`
|
|
118
123
|
|
|
@@ -128,13 +133,37 @@ omdispatch-regeln i dispatch-kontraktet.
|
|
|
128
133
|
"approval": null,
|
|
129
134
|
"granskarutslag": [],
|
|
130
135
|
"note": null,
|
|
136
|
+
"stopp": null,
|
|
137
|
+
"respec_varv": 0,
|
|
138
|
+
"coverage_post": null,
|
|
131
139
|
"runs": []
|
|
132
140
|
}
|
|
133
141
|
```
|
|
134
142
|
|
|
135
143
|
- `bundle` = specar ur samma önskemål (sätts av speca vid bunt).
|
|
136
144
|
`split` = delposter ur ett DELA_UPP-utfall (sätts av bedöm). Båda formen
|
|
137
|
-
`{parent…, part: N, of: M}`.
|
|
145
|
+
`{parent…, part: N, of: M}`. Aldrig båda på samma katalog.
|
|
146
|
+
- `stopp` = ett stopputfall som scripten bevisat utan scorer:
|
|
147
|
+
`{ "utfall": "KONCEPT" | "DIAGNOS" | "TILLBAKA_TILL_SPEC" | "ESKALERA", "kalla": "spec.md" | "impact.md" | "granskarblock.md", "date": "YYYY-MM-DD", "orsak"?: string }`.
|
|
148
|
+
Skrivs BARA av `archive.mjs stopp` (som själv kontrollerar att källan bär
|
|
149
|
+
det påstådda: kandidatmarkören i `spec.md`, etiketten `motsägelse` i
|
|
150
|
+
`impact.md`, det prisavgörande öppna valet i `granskarblock.md`, ADR-0118)
|
|
151
|
+
och nollas BARA av `archive.mjs respec`. `orsak` sätts när `utfall` är
|
|
152
|
+
`ESKALERA` (kommandot kräver `--orsak` då, så en människa ser varför posten
|
|
153
|
+
inte gick tillbaka till specen en gång till) och saknas annars.
|
|
154
|
+
`archive.mjs set-status priced` vägrar medan fältet är satt. Äldre arkiv
|
|
155
|
+
saknar fältet och läses som `null`.
|
|
156
|
+
- `respec_varv` är en monoton räknare, höjd med 1 av varje `archive.mjs
|
|
157
|
+
respec`-anrop (#505), aldrig nollad. Grinden i bedöm läser den för att
|
|
158
|
+
avgöra om ett kvarstående prisavgörande öppet val ska stoppa med
|
|
159
|
+
`TILLBAKA_TILL_SPEC` (första varvet) eller `ESKALERA` (andra varvet och
|
|
160
|
+
senare): en post går aldrig en tredje specrunda på samma val. Äldre arkiv
|
|
161
|
+
saknar fältet och läses som `0`.
|
|
162
|
+
- `coverage_post` speglar score-kuvertets valfria `coverage_post: { yta,
|
|
163
|
+
omfattning }` (ADR-0119). `archive.mjs add-run` kopierar fältet från den
|
|
164
|
+
senaste pricing-filen som bär det, skelettet (`ny-korning`/`ny-del`) sätter
|
|
165
|
+
det till `null`. `bluf` visar `täckningspost: <yta>` i `anm`-kolumnen när
|
|
166
|
+
fältet är satt.
|
|
138
167
|
- `approval` skrivs av grinden i bedöm:
|
|
139
168
|
`{ "source": "asana" | "manual", "by": "<namn, krävs vid manual>",
|
|
140
169
|
"status_read": "<värde>", "date": "YYYY-MM-DD" }`.
|
|
@@ -215,23 +244,29 @@ omdispatch-regeln i dispatch-kontraktet.
|
|
|
215
244
|
Modellkörningar från `utvärdera` bor i ett eget träd och är aldrig prisposter:
|
|
216
245
|
|
|
217
246
|
```
|
|
218
|
-
<repo-rot>/.haus/requests/experiments/<slug>/
|
|
247
|
+
<repo-rot>/.haus-workflow/requests/experiments/<slug>/
|
|
219
248
|
├── experiment.json ticketreferens, datum, modellista, manifest-hash,
|
|
220
249
|
│ status per körning
|
|
221
250
|
├── <modell>/ `default` som modellvärde ger katalognamnet
|
|
222
251
|
│ `baseline/`
|
|
223
252
|
│ ├── k1/
|
|
224
|
-
│ ├── k1/
|
|
253
|
+
│ ├── k1/steg/ råsvaret per agentsteg (claude -p-JSON), inklusive
|
|
254
|
+
│ │ omdispatcher och kundtextfixar
|
|
255
|
+
│ ├── k1/korning.json summan över stegen: USD, tokens, modelUsage, antal
|
|
256
|
+
│ │ steg (report.mjs läser samma nycklar som förut)
|
|
225
257
|
│ ├── k1/matning.json startarens egen mätning: startad, avslutad, wall_ms
|
|
226
258
|
│ ├── k2/ senare körning av SAMMA modell
|
|
227
|
-
│ └── k2/del-1/ … delkataloger
|
|
259
|
+
│ └── k2/del-1/ … delkataloger: bunt ur speca (`bundle`) eller
|
|
260
|
+
│ delning ur DELA_UPP (`split`), aldrig båda
|
|
228
261
|
└── <annan modell>/k1/ …
|
|
229
262
|
```
|
|
230
263
|
|
|
231
|
-
- **Två filer, två ägare.** `korning.json`
|
|
232
|
-
|
|
233
|
-
haus-nyckel
|
|
234
|
-
|
|
264
|
+
- **Två filer, två ägare.** `korning.json` skrivs av `korning.mjs` som summan
|
|
265
|
+
över stegens råsvar, som ligger orörda i `steg/`; `matning.json` är
|
|
266
|
+
startarens klocka. En haus-nyckel i ett råsvar under `steg/` skulle göra det
|
|
267
|
+
till ett blandat format; summan bär därför sina egna nycklar
|
|
268
|
+
(`korningsmotor`, `steg`, `modellverifiering`) och råsvaren rörs aldrig
|
|
269
|
+
(ADR-0113 amends ADR-0094).
|
|
235
270
|
- **Ingen körning skrivs någonsin över.** Värdet i en gammal körning är att
|
|
236
271
|
kunna jämföra samma modell före och efter en ändring i skillen eller
|
|
237
272
|
agentprompterna; skriver en ny körning över den är den jämförelsen borta för
|
|
@@ -240,13 +275,28 @@ Modellkörningar från `utvärdera` bor i ett eget träd och är aldrig prispost
|
|
|
240
275
|
bytetroget (spec.md, granskarblock.md, impact.md, pricing-JSON, state.json,
|
|
241
276
|
`runs[]`-reglerna), så `precheck.mjs` och `contract-check.mjs` fungerar
|
|
242
277
|
oförändrade, de pekas bara på `<modell>/k<N>/`. Proveniensen följer med gratis.
|
|
278
|
+
- **Buntregeln: `del-N/` är antingen bunt eller delning, aldrig båda.** En
|
|
279
|
+
bunt ur speca (flera specar ur samma önskemål) läggs som `del-1/ … del-N/`
|
|
280
|
+
under körningskatalogen med `bundle` satt i varje dels `state.json`; en
|
|
281
|
+
delning ur DELA_UPP läggs likadant men med `split` satt. Del 1 ligger ALDRIG
|
|
282
|
+
i körningsroten: roten bär bara `state.json` (skelettet `ny-korning` skrev),
|
|
283
|
+
`korning.json` och `matning.json`, så en rot utan `spec.md` men med delar
|
|
284
|
+
läses som `bunt (N delar)` av `bluf` och rapporten. DELA_UPP inuti en
|
|
285
|
+
buntdel ger `del-N/del-M`. `sparr`, `precheck` och `stopp` körs per del;
|
|
286
|
+
`proveniens` och `bluf` pekas på `k<N>` och går rekursivt genom delarna.
|
|
287
|
+
**Produktionslayouten är oförändrad** (`speca` steg 5: del 1 behåller
|
|
288
|
+
gid-katalogen, syskonen blir `<slug>-N`); det är `korning.mjs` som väljer
|
|
289
|
+
experimentlayouten, alltid mot katalogen `--katalog` pekar ut.
|
|
243
290
|
- **Numret allokeras aldrig av skillen själv**, alltid med
|
|
244
|
-
`archive.mjs ny-korning <modellkatalog
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
-
|
|
249
|
-
|
|
291
|
+
`archive.mjs ny-korning <modellkatalog> [--request-id <gid eller slug>]`,
|
|
292
|
+
som skapar katalogen atomiskt, skriver skelettet till dess `state.json`
|
|
293
|
+
(`"experiment": true`, `"stopp": null`, `approval: null`, tomma `runs[]`)
|
|
294
|
+
och skriver katalogens sökväg på stdout. Två samtidiga processer, till
|
|
295
|
+
exempel två Claude-konton mot samma checkout, får då `k2` och `k3`,
|
|
296
|
+
aldrig samma katalog. Räknar skillen själv förlorar den ena processens
|
|
297
|
+
körning tyst.
|
|
298
|
+
- `state.json` i en körningskatalog bär markören `"experiment": true` ur
|
|
299
|
+
skelettet. `approval` förblir `null` och `status` blir ALDRIG `priced`: ett
|
|
250
300
|
experimentresultat kan inte förväxlas med en prispost.
|
|
251
301
|
- Katalognamnet `experiments` är reserverat: en spec vars rubrik skulle sluggas
|
|
252
302
|
till `experiments` får suffixet `-post`.
|
|
@@ -254,8 +304,9 @@ Modellkörningar från `utvärdera` bor i ett eget träd och är aldrig prispost
|
|
|
254
304
|
körning: `"klar"`, `"ofärdig"`, `"stopp"`, `"väntar på dom"`. Literalerna
|
|
255
305
|
skrivs exakt så, mellanslag och diakritiska tecken inkluderade. Äldre filer
|
|
256
306
|
med `baselinemodell` och `kandidatmodell` läses utan fel; nya skrivningar
|
|
257
|
-
använder bara `varianter`.
|
|
258
|
-
|
|
307
|
+
använder bara `varianter`. Filen skrivs BARA av `archive.mjs experiment`
|
|
308
|
+
(se `utvärdera` steg 1), aldrig för hand.
|
|
309
|
+
- `experiments/` ärver gitignore-skyddet från `.haus-workflow/requests/`.
|
|
259
310
|
|
|
260
311
|
## Uppgift: `speca`
|
|
261
312
|
|
|
@@ -267,6 +318,17 @@ Modellkörningar från `utvärdera` bor i ett eget träd och är aldrig prispost
|
|
|
267
318
|
(vyer/termer önskemålet nämner), tidigare specar för samma kund (arkivet +
|
|
268
319
|
brädan), ev. brief. **Alla sökvägar i manifestet absoluta.** Finns inget repo
|
|
269
320
|
i sessionen: skriv `KÄLLOR: inga — allt blir antaganden` så specifiern vet.
|
|
321
|
+
Starten avgör samtidigt två rader som specifiern aldrig får gissa:
|
|
322
|
+
`SPRÅK:` (`svenska` eller `engelska`, avläst ur önskemålets brödtext;
|
|
323
|
+
rubrikskelettet i `RUBRIKER:` följer det språket, se promptmallen) och
|
|
324
|
+
`DEPS:` (`installerade` när `node_modules/` eller motsvarande finns under
|
|
325
|
+
REPO-ROT, annars `saknas`; utan repo alltid `saknas`).
|
|
326
|
+
Skriv manifestet till `<katalog>/kallmanifest.md` i varje katalog specen
|
|
327
|
+
arkiveras i (steg 5), så att `bedöm` kan ge assessorn samma manifest utan
|
|
328
|
+
att bygga ett nytt.
|
|
329
|
+
Manifestet har sist sektionen `## Avgjorda val`: varje val som en människa
|
|
330
|
+
avgjort efter ett tidigare stopp, en rad var, ordagrant som svaret gavs;
|
|
331
|
+
`inga` om inga. Specifiern får aldrig flagga ett val som står där.
|
|
270
332
|
3. **Eskaleringsbedömning.** Misstänkt bunt (flera beslut), behörighet/betalning/
|
|
271
333
|
oåterkallelig data/personuppgifter, eller offertunderlag → utfallet är
|
|
272
334
|
prisbärande och eskaleringen är ett MODELLBYTE, inte en flagga: dispatcha
|
|
@@ -274,10 +336,15 @@ Modellkörningar från `utvärdera` bor i ett eget träd och är aldrig prispost
|
|
|
274
336
|
`request-specifier`, med `ESKALERAD: ja` plus orsaken i prompten.
|
|
275
337
|
4. **Dispatcha `request-specifier`** (eller den eskalerade varianten enligt
|
|
276
338
|
steg 3) enligt promptmallen i dispatch-kontraktet.
|
|
277
|
-
5. **Arkivera.**
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
339
|
+
5. **Arkivera.** Specifierns svar delas per spec (ADR-0118): varje titelrad
|
|
340
|
+
startar en ny spec, och specens EGET `## Till granskaren`-block avslutar
|
|
341
|
+
den. Ett svar med bara ETT block efter flera specar (gamla formatet) är en
|
|
342
|
+
brist: `korSpecifier` dispatchar om HELA specifierprompten en gång med
|
|
343
|
+
`RÄTTNINGAR:` innan någon katalog skapas, och kvarstår bristen (delat block
|
|
344
|
+
eller ett saknat block) blir steget `ofärdig` direkt, utan katalog. En
|
|
345
|
+
spec → en katalog: VARJE spec får sin egen katalog med egen `spec.md`,
|
|
346
|
+
eget `granskarblock.md` (delens eget block, aldrig ett kopierat) och eget
|
|
347
|
+
`state.json` (bunt: `bundle`-fältet ifyllt). Bunt ur en gid-post:
|
|
281
348
|
del 1 behåller gid-katalogen, resterande delar får slug-kataloger med
|
|
282
349
|
`bundle.parent_slug` satt till gid:t; syskontasks på brädan mintas först
|
|
283
350
|
vid sync. Stämpla varje berörd `state.json` med
|
|
@@ -289,11 +356,14 @@ på request-write-spec/references/specformat.md>`. Scriptet sätter
|
|
|
289
356
|
referens-hashen måste sättas explicit precis som för poängen, annars
|
|
290
357
|
tappas specformatets proveniens (se runs-kontraktet).
|
|
291
358
|
**Respec över befintlig katalog invaliderar analysen:** när `spec.md`
|
|
292
|
-
ersätts
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
359
|
+
ersätts i en katalog som redan har en, kör
|
|
360
|
+
`node <skillkatalog>/scripts/archive.mjs respec <katalog>` INNAN den nya
|
|
361
|
+
specen skrivs. Kommandot äger hela invalideringen (analysen läggs undan
|
|
362
|
+
som superseded, status, `approval`, `granskarutslag` och `stopp` återställs,
|
|
363
|
+
`runs[]` rörs aldrig); skriv aldrig de fälten för hand. Skälet står i
|
|
364
|
+
runs-kontraktet: en ny spec är ogranskad per definition, ett utslag mot en
|
|
365
|
+
ersatt spec är inte längre giltigt, och en gammal analys mot ny spec är
|
|
366
|
+
exakt den skevhet proveniens-kontrollen finns för att stoppa.
|
|
297
367
|
6. **Formkontroll.** Kör `node <skillkatalog>/scripts/precheck.mjs <katalog>`
|
|
298
368
|
per katalog. BRISTER i spec/granskarblock → dispatcha om specifiern EN gång
|
|
299
369
|
enligt omdispatch-regeln. **Det förkastade utkastet får kvitto
|
|
@@ -304,9 +374,35 @@ på request-write-spec/references/specformat.md>`. Scriptet sätter
|
|
|
304
374
|
dispatch får sin egen runs-rad — även den förkastade — så arkivet bär
|
|
305
375
|
både att ett omtag skedde och varför; en spec godkänd i andra försöket
|
|
306
376
|
får aldrig se ut som en som blev rätt direkt.
|
|
377
|
+
**Omdispatch gäller endast den spec som föll.** I en bunt rörs de specar
|
|
378
|
+
som passerade inte: omdispatchprompten bär hela ursprungsprompten plus
|
|
379
|
+
`RÄTTNINGAR:` med felraderna för just den specen och raden
|
|
380
|
+
`Returnera endast spec <N>`; svaret ersätter bara den katalogens utkast.
|
|
381
|
+
**Kvarstår brist efter omdispatch blir utkastet aldrig `spec.md`:** även
|
|
382
|
+
det andra utkastet arkiveras som `spec-avvisad-<datum>.md` med egen
|
|
383
|
+
runs-rad, katalogen står utan `spec.md` och behåller status `spec_draft`,
|
|
384
|
+
och i `utvärdera` blir körningen `"ofärdig"`. Visa bristerna och stanna.
|
|
385
|
+
**Kandidat stoppas här, aldrig i bedöm.** Skriver precheck raden
|
|
386
|
+
`KANDIDAT: KONCEPT` eller `KANDIDAT: DIAGNOS` (specen bär markörraden ur
|
|
387
|
+
specformatets kandidatform), kör direkt
|
|
388
|
+
`node <skillkatalog>/scripts/archive.mjs stopp <katalog> --utfall <utfallet ur raden> --kalla spec.md`
|
|
389
|
+
på den katalogen: en kandidat har inget analys- eller poängsteg att vänta
|
|
390
|
+
på, och `stopp`-fältet är det som gör utfallet synligt för `bluf`,
|
|
391
|
+
rapporten och `set-status`. Kandidatens katalog kan fortfarande läggas på
|
|
392
|
+
brädan i steg 7 (kunddialogen är nästa steg för den), men `bedöm` hoppar
|
|
393
|
+
över den.
|
|
394
|
+
**Prisavgörande öppet val stoppas här (ADR-0118).** Skriver precheck raden
|
|
395
|
+
`PRISAVGORANDE: <valet>` (granskarblockets rad `Prisavgörande öppet val:
|
|
396
|
+
ja: …`), kör `archive.mjs stopp <katalog> --utfall TILLBAKA_TILL_SPEC
|
|
397
|
+
--kalla granskarblock.md` och visa valet i kundens språk; ingen assessor.
|
|
398
|
+
Är `state.json.respec_varv` redan ≥ 1 kör i stället `--utfall ESKALERA
|
|
399
|
+
--kalla granskarblock.md --orsak "prisavgörande val kvarstår efter respec:
|
|
400
|
+
<valet>"`: en människa dömer, posten går aldrig en tredje specrunda. När
|
|
401
|
+
valet avgjorts skrivs svaret under `## Avgjorda val` i manifestet, sedan
|
|
402
|
+
`respec` och ny specifier-dispatch.
|
|
307
403
|
BRISTER i `state.json` är wrapperns egna filer och
|
|
308
|
-
rättas av wrappern själv, aldrig via omdispatch.
|
|
309
|
-
|
|
404
|
+
rättas av wrappern själv, aldrig via omdispatch. VARNING:ar visas men
|
|
405
|
+
stoppar inget.
|
|
310
406
|
7. **Svara BLUF:** en rad per spec (rubrik + ev. flaggor), sedan granskarblocket
|
|
311
407
|
i sin helhet. Erbjud att lägga specarna på brädan via request-sync (🔍) — gör
|
|
312
408
|
det bara på uttrycklig begäran. När en post läggs på brädan: sätt status
|
|
@@ -325,7 +421,7 @@ driftvakt.
|
|
|
325
421
|
Endast `✅ Spec ok` (normaliserad på alfabetiska kärnan) släpper igenom.
|
|
326
422
|
Annan status: visa den och stanna. En inklistrad spec för en post som har
|
|
327
423
|
gid räknas inte — det är brädstatusen som gäller, läs den ändå.
|
|
328
|
-
- **Posten saknar gid MEN repot har `.haus/request.json`:** vägra — repot är
|
|
424
|
+
- **Posten saknar gid MEN repot har `.haus-workflow/request.json`:** vägra — repot är
|
|
329
425
|
kopplat till en bräda, så en gid-lös post ska in via intaget och granskas
|
|
330
426
|
där, inte prissättas vid sidan av. Grinden är värd något bara om den inte
|
|
331
427
|
går att kliva runt.
|
|
@@ -343,53 +439,93 @@ driftvakt.
|
|
|
343
439
|
specblock är en BRIST — dela posten enligt arkivregeln innan något dispatchas.
|
|
344
440
|
Övriga BRISTER → åtgärda ledet som brister (om spec: tillbaka till
|
|
345
441
|
speca-steget) innan något dyrt dispatchas.
|
|
442
|
+
**`KANDIDAT:`-raden avgör före allt annat.** Skriver precheck
|
|
443
|
+
`KANDIDAT: KONCEPT` eller `KANDIDAT: DIAGNOS` (raden kommer alltid, även
|
|
444
|
+
vid exit 1) är posten en kandidat: hoppa över steg 3 till 7, kör
|
|
445
|
+
`archive.mjs stopp <katalog> --utfall <utfallet ur raden> --kalla spec.md`
|
|
446
|
+
om `stopp` inte redan är satt (speca steg 6 brukar ha gjort det;
|
|
447
|
+
ett identiskt omanrop är ofarligt), och routa posten som stopputfallet
|
|
448
|
+
nedan. Ingen analys och ingen poäng får någonsin dispatchas på en
|
|
449
|
+
kandidat.
|
|
346
450
|
3. **Analys.** Saknas `impact.md`, eller fäller precheck den på
|
|
347
451
|
underlagsproveniens (analysen gjordes mot en annan spec): kräver repo i
|
|
348
452
|
sessionen (annars stopp — en gissad analys är förbjuden av skillen själv).
|
|
349
453
|
Dispatcha `request-assessor` enligt promptmallen — specens granskarblock
|
|
350
454
|
skickas med som internt underlag (samma förtroendedomän; flaggorna där är
|
|
351
|
-
ofta analysens viktigaste ingång).
|
|
455
|
+
ofta analysens viktigaste ingång). Promptens `KÄLLOR:`-rad bär
|
|
456
|
+
`kallmanifest.md` ur katalogen ordagrant, eller `inga` när filen saknas;
|
|
457
|
+
assessorn verifierar manifestet själv och ska aldrig ta det för sant
|
|
458
|
+
(ADR-0113: assessorn utforskade repot från noll trots att manifestet redan
|
|
459
|
+
fanns). Arkivera svaret som `impact.md`
|
|
352
460
|
(inklusive dess "## Till granskaren"-block — visa blocket för användaren,
|
|
353
461
|
aldrig till kundfält), stämpla med
|
|
354
462
|
`node <skillkatalog>/scripts/archive.mjs add-run <katalog> --file impact.md
|
|
355
463
|
--skill request-assess-impact --agent request-assessor
|
|
356
464
|
--model <ur MODELL-svansraden>` (scriptet sätter `underlag_sha256` mot
|
|
357
|
-
`spec.md`). Kör precheck igen med `--impact`.
|
|
465
|
+
`spec.md`). Kör precheck igen med `--impact`. Läs sedan raden
|
|
466
|
+
`AVVIKELSE: <etikett>` ur precheck-utskriften (etiketten på analysens rad
|
|
467
|
+
`**Avvikelse mot specen:**`; inte att förväxla med agenternas svansrad):
|
|
468
|
+
`motsägelse` betyder att specen förutsätter något som inte stämmer i
|
|
469
|
+
systemet, och då kör
|
|
470
|
+
`node <skillkatalog>/scripts/archive.mjs stopp <katalog> --utfall TILLBAKA_TILL_SPEC --kalla impact.md`
|
|
471
|
+
(kommandot sätter status `assessed`), hoppa över steg 4 till 7 och routa
|
|
472
|
+
posten som stopputfallet nedan: ingen scorer dispatchas på ett underlag
|
|
473
|
+
som redan säger att specen måste tillbaka. `ingen` och `precisering` går
|
|
474
|
+
vidare till steg 4. Fäller precheck det nya
|
|
358
475
|
utkastet → omdispatcha assessorn EN gång enligt omdispatch-regeln, och ge
|
|
359
476
|
det förkastade utkastet kvitto precis som i speca steg 6: arkivera det som
|
|
360
477
|
`impact-avvisad-<datum>.md` och stämpla en egen runs-rad med kontrollens
|
|
361
478
|
felrader i `--note` (ADR-0099).
|
|
362
479
|
4. **Prissättning.** Dispatcha `request-scorer` enligt promptmallen.
|
|
363
480
|
Ingen prislista, inget repo, inga andra posters dokument i prompten.
|
|
364
|
-
5. **Ankarlösning och kontraktskontroll.**
|
|
365
|
-
|
|
366
|
-
`node <skillkatalog>/scripts/
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
`
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
`
|
|
373
|
-
|
|
481
|
+
5. **Ankarlösning och kontraktskontroll.** Skriv agentens hela svarstext (JSON
|
|
482
|
+
plus svansrader) till fil och kör
|
|
483
|
+
`node <skillkatalog>/scripts/kontroll.mjs <svar.txt> <spec.md> <impact.md> --expect-id <katalogens id> --ut <svar.json> --fixa-kundtext --state <katalog>/state.json`.
|
|
484
|
+
`--state` ger contract-check split-status: `OVER_SKALAN` på något som inte
|
|
485
|
+
är en split-del fälls, och ett inget-tak-utfall utan steg mot A16 fälls
|
|
486
|
+
(#503). Scriptet strippar svansraderna (`MODELL:`, `LÄSTA:`, ev. `AVVIKELSE:`),
|
|
487
|
+
reparerar det dispatchern redan vet (`request_id`, enumform,
|
|
488
|
+
siffersträngar, LÄSTA-radens sökvägsform) och kör check-lasta,
|
|
489
|
+
`resolve-anchors.mjs` (beläggsankare till ordagranna källblock;
|
|
490
|
+
OLÖST/FLERTYDIG är ett kontraktsbrott) och contract-check i en process; ett
|
|
491
|
+
protokollterm-brott i ett rent kundtextfält skrivs om av en billig modell i
|
|
492
|
+
stället för att kosta en ny scorerkörning. `REPARERAT:`-raderna visas i
|
|
493
|
+
BLUF-svaret och skrivs i runs-radens `--note`.
|
|
494
|
+
`impact.md` skickas ALLTID med till contract-check, aldrig bara specen:
|
|
495
|
+
scriptet läser etiketten på `**Avvikelse mot specen:**` och fäller varje
|
|
496
|
+
annat utfall än TILLBAKA_TILL_SPEC när analysen bär `motsägelse`
|
|
497
|
+
(motsägelsegrinden i scriptet är bältet, steg 3 hängslena; en post som
|
|
498
|
+
ändå nått hit har ett underlag scriptet ska få se). Samma script kräver
|
|
499
|
+
att varje `bracket.steps[i]` är exakt `{anchor, relation, grund}`.
|
|
500
|
+
BROTT som kvarstår efter reparationerna → omdispatch EN gång enligt
|
|
374
501
|
omdispatch-regeln, med felraderna i prompten. Kvarstår brott: visa dem och
|
|
375
502
|
stanna utan att arkivera svaret som giltigt varv, men släng det inte:
|
|
376
503
|
arkivera som `score-pricing-vN-avvisad.json` (utanför N-räkningen) med
|
|
377
504
|
kontrollens felrader i en runs-rad, så även misslyckade körningar har
|
|
378
505
|
kvitto. En `AVVIKELSE:`-rad visas alltid för användaren.
|
|
379
|
-
6. **Dubbelkörning (driftvakt).**
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
506
|
+
6. **Dubbelkörning (driftvakt).** Körning 2 startar ALLTID samtidigt med
|
|
507
|
+
körning 1, med samma prompt och i en ny isolerad körning; i produktion
|
|
508
|
+
dispatchas båda Agent-anropen på en gång (#500, ADR-0113), promptarna är
|
|
509
|
+
identiska och körningarna oberoende. Trigger: poängen är ≥ 1 (ADR-0098),
|
|
510
|
+
eller utfallet är `OVER_SKALAN` (ADR-0116: det utfallet skickar posten
|
|
511
|
+
till manuell offert och är prisbärande; två OVER_SKALAN med olika golv är
|
|
512
|
+
OLIKA och går till dom). Övriga stopputfall dubbelkörs inte: DELA_UPP körs
|
|
513
|
+
om per del, KONCEPT/DIAGNOS/TILLBAKA_TILL_SPEC går till människa ändå.
|
|
514
|
+
Tröskeln avgör bara om paret RÄKNAS som dubbelkörning, aldrig om
|
|
515
|
+
körning 2 startar. Blir körning 1 ett stopputfall utom OVER_SKALAN, eller
|
|
516
|
+
poäng under 1, arkiveras körning 2 som `-run2` med `superseded_by` mot
|
|
517
|
+
huvudfilen och en notering om att den inte krävdes, den räknas aldrig som
|
|
518
|
+
dubbelkörning, och stopproutningen nedan gäller som förut. I övriga fall
|
|
519
|
+
jämförs paret som nedan; skillens eget acceptanstest är att två oberoende
|
|
520
|
+
körningar ger samma resultat.
|
|
389
521
|
- Kör hela steg 5 (ankarlösning, sedan kontraktskontroll) på det nya
|
|
390
522
|
svaret först, med egen omdispatch-budget (EN).
|
|
391
523
|
- Jämför sedan deterministiskt:
|
|
392
|
-
`node <skillkatalog>/scripts/compare-scores.mjs <poäng1.json> <poäng2.json
|
|
524
|
+
`node <skillkatalog>/scripts/compare-scores.mjs <poäng1.json> <poäng2.json>`.
|
|
525
|
+
Scriptet diffar även de inre stegen: samma ankare i `bracket.steps` läst
|
|
526
|
+
som `storre` i ena körningen och `mindre` i den andra är en hård diffrad
|
|
527
|
+
(OLIKA), aldrig en toleransrad. Golv- och takankaren är undantagna, de
|
|
528
|
+
flippar av konstruktion när banden angränsar och ägs av toleransregeln.
|
|
393
529
|
- **LIKA** → körning 1 gäller: `double_run: "bekräftad"` på dess
|
|
394
530
|
runs-rad. Körning 2-filen arkiveras som `score-pricing-vN-run2.json`
|
|
395
531
|
med SAMMA N och `superseded_by` satt till körning 1-filen.
|
|
@@ -417,7 +553,11 @@ driftvakt.
|
|
|
417
553
|
skillnaden ligger inom toleransen. Sätt `double_run: "tolerans"` på
|
|
418
554
|
bägge runs-raderna. Toleransen är en medveten prisregel: högsta
|
|
419
555
|
värdet skyddar marginalen, och ett medelvärde räknas fortfarande
|
|
420
|
-
aldrig fram. Visa toleransraderna i BLUF-svaret.
|
|
556
|
+
aldrig fram. Visa toleransraderna i BLUF-svaret. Ett par av två
|
|
557
|
+
`OVER_SKALAN` med SAMMA golv där bara konfidensen skiljer skriver
|
|
558
|
+
också `LIKA_TOLERANS`, men utan poäng att jämföra (OVER_SKALAN bär
|
|
559
|
+
`score: null`) vinner körning 1 deterministiskt, aldrig "högsta
|
|
560
|
+
poängen" (ADR-0116).
|
|
421
561
|
- Exit 2 från jämförelsescriptet är ett dispatcherfel (ojämförbara
|
|
422
562
|
körningar) — visa felet och stanna, rapportera aldrig LIKA.
|
|
423
563
|
7. **Arkivera** godkända JSON-svar. Hämta varvets N med
|
|
@@ -425,14 +565,18 @@ driftvakt.
|
|
|
425
565
|
skriv filerna (`score-pricing-vN.json`, körning 2
|
|
426
566
|
som `-run2`, avvisade som `-avvisad`), och stämpla VARJE körning med
|
|
427
567
|
`archive.mjs add-run` (flaggor för fil, skill, agent, modell ur
|
|
428
|
-
MODELL-svansraden
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
568
|
+
MODELL-svansraden som förut, referens-hash via `--ref` för skillens
|
|
569
|
+
referensfil (se runs-kontraktet), double-run-utfall, superseded-by,
|
|
570
|
+
partial-rerun och pairs-with där de gäller). Effort läser scriptet självt
|
|
571
|
+
ur agentdefinitionen under Claude-konfigkatalogen när `--effort`
|
|
572
|
+
utelämnas, så utelämna flaggan; `--model` förblir obligatorisk och kommer
|
|
573
|
+
ur svansraden, aldrig ur definitionen (under `utvärdera` körs agenterna
|
|
574
|
+
med override, så definitionens modell är per konstruktion inte den som
|
|
575
|
+
kördes). Exempel för huvudfilen vid ett bekräftat par:
|
|
432
576
|
`node <skillkatalog>/scripts/archive.mjs add-run <katalog>
|
|
433
577
|
--file score-pricing-v1.json --skill request-score
|
|
434
578
|
--agent request-scorer --model <ur MODELL-svansraden>
|
|
435
|
-
--
|
|
579
|
+
--ref poangskala.md=<hash via
|
|
436
580
|
ref-hash.mjs på request-score/references/poangskala.md>
|
|
437
581
|
--double-run bekräftad`. `--double-run` tar ENDAST de tre
|
|
438
582
|
literalerna `bekräftad`, `olika` eller `tolerans` (scriptet vägrar allt
|
|
@@ -444,7 +588,12 @@ ref-hash.mjs på request-score/references/poangskala.md>
|
|
|
444
588
|
`archive.mjs set-status <katalog> priced` (scriptet vägrar vid spärr,
|
|
445
589
|
stopputfall och experiment — se runs-kontraktet)
|
|
446
590
|
eller `assessed`.
|
|
447
|
-
8. **Svara BLUF:**
|
|
591
|
+
8. **Svara BLUF:** tabellen kommer ur
|
|
592
|
+
`node <skillkatalog>/scripts/archive.mjs bluf <katalog>` och klistras in
|
|
593
|
+
som den är (`| post | poäng | utfall | konfidens | anm |`, en rad per
|
|
594
|
+
katalog och del; poängen ur filerna, stopputfall ur `stopp`, OLIKA och
|
|
595
|
+
tolerans i `anm`), ALDRIG handskriven: en handskriven tabell
|
|
596
|
+
felrapporterade i skarp körning. Under tabellen en rad
|
|
448
597
|
per avvikelse värd att se (ESKALERA, DELA_UPP,
|
|
449
598
|
INPUT_SAKNAS, AVVIKELSE-rader). JSON:en visas inte i chatten —
|
|
450
599
|
`detaljer <post>` gör det. Skriv-tillbaka till brädan sker via request-sync
|
|
@@ -458,14 +607,23 @@ fil (steg 7), statusen blir `assessed`, aldrig `priced`, och posten routas:
|
|
|
458
607
|
- `DELA_UPP` → föreslå ny analysrunda per del; delarna blir egna kataloger med
|
|
459
608
|
`split` satt (`part`/`of`), och en del utan tak blir `OVER_SKALAN`, aldrig
|
|
460
609
|
DELA_UPP igen. Delposter ärver enligt skillen postens spec och skriver aldrig
|
|
461
|
-
en egen: förälderns `spec.md` och `granskarblock.md` KOPIERAS in
|
|
462
|
-
delkatalog
|
|
463
|
-
|
|
610
|
+
en egen: förälderns `spec.md` och `granskarblock.md` KOPIERAS oförändrade in
|
|
611
|
+
i varje delkatalog, var för sig (ett granskarblock per delkatalog, ADR-0118,
|
|
612
|
+
ingen delkatalog delar sitt block med en annan), medan `impact.md` skrivs per
|
|
613
|
+
del av den nya analysrundan.
|
|
464
614
|
- `OVER_SKALAN` → posten offereras separat; delas aldrig vidare (delningen görs
|
|
465
615
|
ett steg, skillens egen regel).
|
|
466
616
|
- `TILLBAKA_TILL_SPEC` / `KONCEPT` / `DIAGNOS` → tillbaka till spec-steget
|
|
467
|
-
respektive kunddialog; visa skälet.
|
|
468
|
-
|
|
617
|
+
respektive kunddialog; visa skälet. Kom utfallet ur scripten (kandidat i
|
|
618
|
+
`spec.md`, `motsägelse` i `impact.md`, prisavgörande öppet val i
|
|
619
|
+
`granskarblock.md`, ADR-0118) bär `state.json.stopp` det via
|
|
620
|
+
`archive.mjs stopp` och det finns ingen varvsfil; kom det ur scorern
|
|
621
|
+
arkiveras varvsfilen som förut och `stopp` förblir `null` (kommandot tar
|
|
622
|
+
bara de tre scriptbevisade källorna: `spec.md`, `impact.md`,
|
|
623
|
+
`granskarblock.md`). En respec nollar `stopp`.
|
|
624
|
+
- `ESKALERA` / `INPUT_SAKNAS` → visa skälet och stanna, eller ett prisavgörande
|
|
625
|
+
val som kvarstår efter respec (källa `granskarblock.md`, orsak i
|
|
626
|
+
`stopp.orsak`, ADR-0118).
|
|
469
627
|
|
|
470
628
|
## Uppgift: `status`
|
|
471
629
|
|
|
@@ -624,12 +782,11 @@ dubbelkörning väntar på `döm`, precis som i produktion.
|
|
|
624
782
|
`utvärdera rapport` (se avsnitten nedan). Argumentreglerna nedan gäller aldrig
|
|
625
783
|
de orden; de klassificeras varken som modell eller post-id.
|
|
626
784
|
|
|
627
|
-
**Flaggorna plockas bort först.** `--om
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
krävs" trots att modellen står där.
|
|
785
|
+
**Flaggorna plockas bort först.** `--om` och `--hoppa-över` lyfts ur
|
|
786
|
+
argumentlistan INNAN skanningen nedan börjar, och räknas varken som modell
|
|
787
|
+
eller post-id. Utan det steget stoppar en flagga skanningen, noll modeller
|
|
788
|
+
hittas, och kommandot faller på "Minst en modell krävs" trots att modellen
|
|
789
|
+
står där.
|
|
633
790
|
|
|
634
791
|
**Argumenttolkning.** Kvarvarande avslutande argument avgörs höger till vänster
|
|
635
792
|
för att hitta GRÄNSEN mot post-id-listan: ett argument räknas som modell bara
|
|
@@ -668,34 +825,62 @@ Frågan gäller alltså kostnaden, inte risken att förlora data.
|
|
|
668
825
|
|
|
669
826
|
1. **Underlag.** Som `speca` steg 1: rått önskemål eller gid — vid gid hämtas
|
|
670
827
|
posten läsande via request-sync i huvudkonversationen, uppgiftens ENDA
|
|
671
|
-
Asana-kontakt. Skapa `experiments/<slug>/` och
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
`
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
828
|
+
Asana-kontakt. Skapa `experiments/<slug>/` och skriv underlaget till disk
|
|
829
|
+
med fasta namn: önskemålet ordagrant som `experiments/<slug>/onskemal.md`
|
|
830
|
+
och källmanifestet (steg 2) som `experiments/<slug>/kallmanifest.md`.
|
|
831
|
+
Namnen är fasta därför att `korning.mjs` (steg 4) läser dem därifrån och
|
|
832
|
+
bygger varje agentprompt av dem; ett underlag som bara finns i
|
|
833
|
+
konversationen når aldrig en headless-process.
|
|
834
|
+
|
|
835
|
+
Skapa sedan `experiment.json` med ticketreferens, datum och `varianter` i
|
|
836
|
+
deklarationsordning, alltid genom kommandot:
|
|
837
|
+
|
|
838
|
+
```
|
|
839
|
+
node <skillkatalog>/scripts/archive.mjs experiment experiments/<slug> \
|
|
840
|
+
--satt request_id=<gid> --satt title=<titel> --satt permalink_url=<url> \
|
|
841
|
+
--satt datum=<YYYY-MM-DD> --satt sprak=<svenska|engelska> --satt manifest_sha256=<hash> \
|
|
842
|
+
--satt eskalerad=<true|false> --satt eskaleringsorsak=<text> \
|
|
843
|
+
--variant <m>...
|
|
844
|
+
```
|
|
845
|
+
|
|
846
|
+
Nyckelnamnen är rapportens: `report.mjs` läser `request_id`, `title`,
|
|
847
|
+
`permalink_url` och `datum`, och `svep.mjs` läser `request_id` (med
|
|
848
|
+
`ticket` som reserv i äldre filer) till varje varvs REQUEST_ID. Äldre
|
|
849
|
+
filer med `ticket`/`titel` läses som förut men skrivs inte längre.
|
|
850
|
+
`manifest_sha256` (steg 2) och `eskalerad`/`eskaleringsorsak` (steg 3)
|
|
851
|
+
sätts när de är kända, i egna anrop av samma kommando; ett fält som redan
|
|
852
|
+
bär samma värde är no-op. `sprak` avläses ur önskemålets brödtext av
|
|
853
|
+
huvudkonversationen, precis som i `speca` steg 2; `korning.mjs` vägrar
|
|
854
|
+
starta utan den (den gissar aldrig språk, ADR-0114).
|
|
855
|
+
|
|
856
|
+
Anteckna samtidigt postens `permalink_url` (`--satt permalink_url=<url>`)
|
|
857
|
+
när gid-svaret bär det. Det kommer ur samma läsande hämtning
|
|
858
|
+
som redan görs, så steget får ingen ny Asana-kontakt. Saknas fältet i
|
|
859
|
+
svaret skrivs det inte, och rapporten visar då gid som ren text: Asanas
|
|
860
|
+
permalänk bär ett workspace-gid som inte finns på experimentytan, så en
|
|
861
|
+
konstruerad URL vore en gissning.
|
|
862
|
+
|
|
863
|
+
**`archive.mjs experiment` är den ENDA skrivaren av `experiment.json`.**
|
|
864
|
+
Ingen process, varken huvudkonversationen, startaren eller den inre
|
|
865
|
+
processen, skriver filen för hand. Kommandot skapar filen om den saknas
|
|
866
|
+
och läser annars in den först: `varianter` slås ihop som UNION med bevarad
|
|
867
|
+
deklarationsordning (befintliga namn först, invokationens nya efter), en
|
|
868
|
+
befintlig körnings `status` skrivs aldrig över av en process som inte äger just den
|
|
869
|
+
körningen, och skrivningen är ATOMISK under ett lås i experimentkatalogen. Skälet till att det är ett kommando: `experiment.json`
|
|
870
|
+
är den enda filen på experimentytan som delas mellan samtidiga processer,
|
|
871
|
+
och låset är det som gör parallella körningar (steg 4) säkra. Utan det
|
|
872
|
+
tappar två samtidiga processer varandras rader, vilket är exakt vad som
|
|
873
|
+
hände sonnet/k4 i IPC 14001 (#493).
|
|
874
|
+
|
|
875
|
+
2. **Källmanifest EN gång.** Bygg manifestet som i `speca` steg 2, skriv det
|
|
876
|
+
till `experiments/<slug>/kallmanifest.md` (steg 1) och
|
|
877
|
+
återanvänd det byteidentiskt i ALLA varv. Anteckna manifest-hash med
|
|
878
|
+
`archive.mjs experiment experiments/<slug> --satt manifest_sha256=<hash>`
|
|
879
|
+
(`ref-hash.mjs` på manifesttexten). Enda avsedda
|
|
698
880
|
skillnaden mellan varven är modellen.
|
|
881
|
+
Manifestet har sist sektionen `## Avgjorda val`: varje val som en människa
|
|
882
|
+
avgjort efter ett tidigare stopp, en rad var, ordagrant som svaret gavs;
|
|
883
|
+
`inga` om inga. Specifiern får aldrig flagga ett val som står där.
|
|
699
884
|
3. **Eskaleringsvalet görs en gång** enligt `speca`:s regler och gäller alla
|
|
700
885
|
varv, även eskaleringsvalet är en del av det som hålls konstant.
|
|
701
886
|
Triggar valet: agenten blir `request-specifier-eskalerad` i stället för
|
|
@@ -705,157 +890,223 @@ Frågan gäller alltså kostnaden, inte risken att förlora data.
|
|
|
705
890
|
över av varvets modell. Eskaleringsmekanismen kollapsar alltså medvetet
|
|
706
891
|
under override, det är avsett, inte en lucka: `utvärdera` mäter en ren
|
|
707
892
|
modellskillnad över alla tre rollerna och testar aldrig
|
|
708
|
-
eskaleringsbeslutet i sig.
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
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.
|
|
722
|
-
|
|
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`:
|
|
893
|
+
eskaleringsbeslutet i sig. Valet antecknas med
|
|
894
|
+
`archive.mjs experiment experiments/<slug> --satt eskalerad=<true|false> --satt eskaleringsorsak=<text>`;
|
|
895
|
+
det är därifrån `svep.mjs` läser `ESKALERAD:` till varje varvs prompt.
|
|
896
|
+
4. **Ett varv per modell i listan**, startat av `svep.mjs`. Huvudkonversationen
|
|
897
|
+
förbereder steg 1 till 3 och kör sedan, även för en enda post och en enda
|
|
898
|
+
modell:
|
|
733
899
|
|
|
734
900
|
```
|
|
735
|
-
node <skillkatalog>/scripts/
|
|
736
|
-
--modell <
|
|
737
|
-
--
|
|
901
|
+
node <skillkatalog>/scripts/svep.mjs --repo-rot <abs> --konto <namn> \
|
|
902
|
+
--modell <modell> [--modell <modell>]... \
|
|
903
|
+
--exp experiments/<slug> [--exp experiments/<slug>]... \
|
|
904
|
+
[--tickets-parallellt 2] [--om | --hoppa-över]
|
|
738
905
|
```
|
|
739
906
|
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
`
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
907
|
+
Varje varv startas av `svep.mjs` som EN `korning.mjs`-process, och det är
|
|
908
|
+
det som ger mätningen gratis. Parallellregeln: två tickets åt gången, alla
|
|
909
|
+
modeller för en ticket startar samtidigt, och nästa ticket startar först när en tickets samtliga
|
|
910
|
+
modeller är klara. Det är säkert därför att körningskatalogerna redan är
|
|
911
|
+
isolerade (`ny-korning` är atomisk, varje varv har egen katalog, manifest
|
|
912
|
+
och repo läses bara) och det enda delade tillståndet, `experiment.json`,
|
|
913
|
+
skrivs under lås (steg 1). Ansvaret delas, eftersom en process aldrig kan känna sin egen
|
|
914
|
+
slutkostnad:
|
|
915
|
+
|
|
916
|
+
**Startaren** är `svep.mjs`. Dess ansvar per varv, i en mening: allokera
|
|
917
|
+
körningskatalogen med
|
|
918
|
+
`archive.mjs ny-korning <modellkatalog> --request-id <gid eller slug>`
|
|
919
|
+
(kommandot skriver också skelettet till körningens `state.json`, se
|
|
920
|
+
Experimentytan; den inre processen skriver aldrig den filen från noll),
|
|
921
|
+
starta `korning.mjs` för varvet med körningskatalogen, experimentkatalogen,
|
|
922
|
+
repo-roten, request-id:t och modellen som argument (stderr till
|
|
923
|
+
`stderr.log`; `korning.json` skriver `korning.mjs` själv),
|
|
924
|
+
ta tiden runt processen och skriva
|
|
925
|
+
`<modell>/k<N>/matning.json` (`startad`, `avslutad`, `wall_ms`,
|
|
926
|
+
`exit_code`; skrivs ÄVEN när processen faller), stämpla `proveniens` i
|
|
927
|
+
körningens `state.json` med
|
|
928
|
+
`archive.mjs proveniens <modell>/k<N> --modell <varvets modellvärde> --konto <Claude-kontot som körde> --underlag <sökväg till kallmanifest.md>`
|
|
929
|
+
EFTER att `korning.json` skrivits, verifiera modellen mot `modelUsage`,
|
|
930
|
+
och sätta körningens status via `archive.mjs experiment`. Hur vart och ett
|
|
931
|
+
görs bor i scriptet och dess tester, inte här. Att stegen står som
|
|
932
|
+
kommandon är med flit (ADR-0094): ett steg som ålägger startaren en
|
|
933
|
+
skrivning utan att peka ut vem som utför den är en skrivning
|
|
749
934
|
som inte blir av, och den syns först som tomma celler långt senare.
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
935
|
+
|
|
936
|
+
Fyra regler i den kedjan är kontrakt mot rapporten och arkivet och står
|
|
937
|
+
därför kvar här med sitt skäl:
|
|
938
|
+
|
|
939
|
+
- **Väggtiden bor i `matning.json`, aldrig i `korning.json`.** Rapporten
|
|
940
|
+
läser `total_cost_usd`, `usage.input_tokens`, `usage.output_tokens`,
|
|
941
|
+
`usage.cache_read_input_tokens`, `usage.cache_creation_input_tokens` och
|
|
942
|
+
`subagent_stats.spawned` ur `korning.json`, men väggtiden ur
|
|
943
|
+
`matning.json`: en process kan inte känna sin egen klocktid när arbetet
|
|
944
|
+
ligger i bakgrundsprocesser, och stegsvarens `duration_ms` räknar inte in väntan på dem.
|
|
945
|
+
`korning.json` bär summan över stegen, därav den egna filen. En kraschad körning har en klocktid, ofta det intressantaste
|
|
946
|
+
talet i tabellen, därför skrivs `matning.json` även vid krasch.
|
|
947
|
+
- **Proveniensen stämplas EFTER `korning.json`, aldrig före**, annars
|
|
948
|
+
saknar stämpeln faktureringsdatan. Kommandot räknar själv `skill_sha256`
|
|
949
|
+
(över `SKILL.md` plus de fyra agentdefinitionerna) och `underlag_sha256`,
|
|
950
|
+
läser `korning.json` och antecknar `fakturerade_modeller` (den
|
|
951
|
+
kanoniserade nyckelmängden ur `modelUsage`, suffix som `[1m]` strippade,
|
|
952
|
+
ADR-0099), och stämplar även varje `del-N/`. Utan den stämpeln går det
|
|
953
|
+
inte att avgöra vad som skilde `k1` från `k2`, och en jämförelse över tid
|
|
954
|
+
blir en gissning.
|
|
955
|
+
- **Modellverifiering görs av startaren mot faktureringen (ADR-0099),
|
|
956
|
+
aldrig mot svansraden ensam.** När processen är klar: jämför
|
|
957
|
+
`fakturerade_modeller` mot varvets begärda modell plus de två tolererade
|
|
958
|
+
avvikelserna, kundtextfixens `sonnet` och CLI:ns `haiku`-hjälpanrop. En
|
|
959
|
+
modellnyckel som varken är varvets begärda modell, kundtextfixens
|
|
960
|
+
`sonnet` eller CLI:ns `haiku`-hjälpanrop är en faktisk MODELL-avvikelse →
|
|
961
|
+
körningen blir `"ofärdig"`. Startaren tolererar `haiku`-nyckeln i summan;
|
|
962
|
+
taket på 200 output-tokens, som skiljer hjälpanropet från en riktig
|
|
963
|
+
körning, prövas per steg av `korning.mjs`. Resultatet ligger i
|
|
964
|
+
`korning.json` som `modellverifiering` (`ok` plus `avvikelser`, där varje
|
|
965
|
+
rad namnger sitt steg), så avvikelsen går att peka ut i det steg den
|
|
966
|
+
uppstod. En MODELL-svansrad som säger något annat än vad
|
|
967
|
+
`modelUsage` visar är en RAPPORTERINGSAVVIKELSE: den visas i rapporten
|
|
968
|
+
och står kvar i `runs[]` (raden bär agentens uppgift i
|
|
969
|
+
`model.uppgiven`), men den fäller ALDRIG ensam körningen — modeller är
|
|
970
|
+
opålitliga källor om sin egen identitet, och att kasta en korrekt
|
|
971
|
+
körning på en felskriven svansrad betalar om ett riktigt resultat.
|
|
972
|
+
Modellvärdet `default` kör agenternas egna defaults och får lagligt
|
|
973
|
+
producera flera modellnycklar: ingen mängdjämförelse görs där.
|
|
974
|
+
- **Statusen sätts via `archive.mjs experiment`**, aldrig genom att skriva
|
|
975
|
+
filen: exit ≠ 0 eller en faktisk MODELL-avvikelse ger `"ofärdig"` med
|
|
976
|
+
`--orsak`; har den inre processen redan satt `"stopp"`, `"väntar på dom"`
|
|
977
|
+
eller `"ofärdig"` behålls den; annars `"klar"`.
|
|
978
|
+
|
|
979
|
+
**`korning.mjs` är den inre processen: ett script utan modellturer.** Det
|
|
980
|
+
bygger prompterna ur `onskemal.md`, `kallmanifest.md` och `experiment.json`,
|
|
981
|
+
startar varje agentsteg som en egen process
|
|
982
|
+
`claude -p --agent <agent> --output-format json --max-turns <tak> [--model <modell>]`
|
|
983
|
+
med prompten på stdin, sparar råsvaret under `k<N>/steg/`, kör precheck,
|
|
984
|
+
`kontroll.mjs` och compare-scores, arkiverar via `archive.mjs` och skriver
|
|
985
|
+
`korning.json` som summan. Det gör ingen Asana-hämtning och bygger inget
|
|
986
|
+
nytt manifest. Buntens delar körs parallellt (två åt gången) och de två
|
|
987
|
+
scorerkörningarna samtidigt (#500).
|
|
988
|
+
|
|
989
|
+
`korning.mjs` kör speca-stegen (dispatch, kontraktskontroll,
|
|
774
990
|
arkivering) och därefter bedöm-stegen (analys, poäng,
|
|
775
991
|
ankarlösning, dubbelkörning enligt bedöm) mot den anvisade katalogen, utan
|
|
776
992
|
godkännandegrind, och rör ingenting utanför den. Är modellen `default`
|
|
777
993
|
används ordinarie promptmallar och agenternas defaults, ingen override. Är
|
|
778
|
-
den ett modellnamn får varje
|
|
779
|
-
tre agenter;
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
994
|
+
den ett modellnamn får varje agentprocess modell-override till den på ALLA
|
|
995
|
+
tre agenter; overriden är `--model` på processen, aldrig en promptrad, och
|
|
996
|
+
agentdefinitionerna röres aldrig, effort tas ur definitionen
|
|
997
|
+
som vanligt. Overriden verifieras per steg mot `modelUsage` i råsvaret
|
|
998
|
+
(ADR-0099, se modellverifieringen ovan), svansraden arkiveras men avgör
|
|
999
|
+
aldrig ensam. `approval` förblir `null`, `state.json`
|
|
1000
|
+
får `"experiment": true` ur skelettet `ny-korning` skrev. `REQUEST_ID`
|
|
1001
|
+
och `--expect-id` använder alltid ticketens gid/slug, aldrig katalogens
|
|
1002
|
+
namn.
|
|
1003
|
+
|
|
1004
|
+
**Bunt i den inre processen:** ger specifiern flera specar läggs de som
|
|
1005
|
+
`del-1/ … del-N/` under körningskatalogen med `bundle` satt (buntregeln i
|
|
1006
|
+
Experimentytan), aldrig del 1 i roten; varje del får sin egen `spec.md`,
|
|
1007
|
+
`granskarblock.md` och `state.json`, och speca steg 6 (precheck,
|
|
1008
|
+
omdispatch per del, `stopp` vid kandidat) körs per del. Faller en del på
|
|
1009
|
+
kvarstående brist blir körningen `"ofärdig"`; övriga delar körs ändå
|
|
1010
|
+
klart så arkivet visar vad som gick att bedöma.
|
|
1011
|
+
|
|
1012
|
+
**DELA_UPP körs inte autonomt av `korning.mjs` (v1).** Utfallet arkiveras
|
|
1013
|
+
och körningen får status `stopp` med orsak; delningsanalysen saknar
|
|
1014
|
+
promptmall i den här skillen, och ett script får inte improvisera en
|
|
1015
|
+
(ADR-0113).
|
|
1016
|
+
|
|
1017
|
+
Ett fallet agentsteg, kontraktsbrott (kvarstående BROTT efter omdispatch) eller
|
|
791
1018
|
en faktisk MODELL-avvikelse (obegärd nyckel i `modelUsage`, aldrig en
|
|
792
1019
|
ensam svansradsavvikelse), i vilket steg det än inträffar, sätter
|
|
793
|
-
körningens `status` till `"ofärdig"`
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
1020
|
+
körningens `status` till `"ofärdig"` via `archive.mjs experiment`
|
|
1021
|
+
(`experiments/<slug> --korning <modell>/k<N> --status ofärdig --orsak <vad som föll>`),
|
|
1022
|
+
aldrig genom att skriva filen.
|
|
1023
|
+
|
|
1024
|
+
5. **DELA_UPP i experimentet.** Ett DELA_UPP-utfall följer bedöms ordinarie
|
|
1025
|
+
delningsregler men utan paus för granskare (i v1 kör `korning.mjs` inte
|
|
1026
|
+
delningen själv, se steg 4; reglerna här gäller när den körs):
|
|
1027
|
+
delkataloger
|
|
797
1028
|
`<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.
|
|
1029
|
+
`granskarblock.md` kopierade in, ny analys + poäng per del. Delas en
|
|
1030
|
+
buntdel blir det `del-N/del-M/` under den delen, aldrig ett nytt
|
|
1031
|
+
syskon i roten (`bundle` och `split` sätts aldrig på samma katalog).
|
|
799
1032
|
En del utan tak blir `OVER_SKALAN` och delas aldrig vidare. Övriga
|
|
800
1033
|
stopputfall (`TILLBAKA_TILL_SPEC`, `KONCEPT`, `DIAGNOS`, `ESKALERA`,
|
|
801
|
-
`INPUT_SAKNAS`) kräver människa eller kund: arkivera utfallet,
|
|
1034
|
+
`INPUT_SAKNAS`) kräver människa eller kund: arkivera utfallet, sätt
|
|
1035
|
+
körningens status till `"stopp"` via `archive.mjs experiment`, avbryt det
|
|
802
1036
|
varvet, gör det synligt i rapporten när den körs, och övriga körningar i
|
|
803
1037
|
listan fortsätter oberoende.
|
|
804
1038
|
|
|
805
1039
|
**OLIKA väntar på dom.** Skriver dubbelkörningen OLIKA i ett varv:
|
|
806
1040
|
arkivera enligt bedöms regler (spärren står), sätt körningens status till
|
|
807
|
-
`"väntar på dom"`
|
|
1041
|
+
`"väntar på dom"` via `archive.mjs experiment`, synligt i rapporten när
|
|
1042
|
+
den körs.
|
|
808
1043
|
Domen är människans även i experimentet: `döm` körs mot körningskatalogen
|
|
809
1044
|
när granskaren vill (adresserad via sin sökväg, se `döm`), och ingen dom
|
|
810
1045
|
simuleras av uppgiften. Domen i sig skriver inte om `experiment.json`,
|
|
811
|
-
det gör `
|
|
1046
|
+
det gör `svep.mjs` (via `archive.mjs experiment`) nästa gång `utvärdera`
|
|
1047
|
+
körs för samma post (se
|
|
812
1048
|
Återupptagbart i avsnittet Batch nedan för hur och när statusen går
|
|
813
1049
|
till `"klar"` och rapporten kan visa utfallet). Övriga körningar i listan
|
|
814
1050
|
fortsätter oberoende oavsett när, eller om, domen fälls.
|
|
815
1051
|
|
|
816
1052
|
6. **Rapport.** BLUF i chatten: klart eller ofärdigt per körning, stopputfall,
|
|
817
|
-
och sökvägen till `experiments/<slug>/`.
|
|
1053
|
+
och sökvägen till `experiments/<slug>/`. Tabellen per körning kommer ur
|
|
1054
|
+
`node <skillkatalog>/scripts/archive.mjs bluf <modell>/k<N>` (rekursivt
|
|
1055
|
+
över delarna, rotraden för en bunt lyder `bunt (N delar)`) och klistras in
|
|
1056
|
+
som den är, aldrig handskriven. Nämn att `utvärdera rapport` finns
|
|
818
1057
|
när underlaget ska läsas sida vid sida. Ingen skrivning mot Asana.
|
|
819
1058
|
|
|
820
1059
|
### Batch: flera poster
|
|
821
1060
|
|
|
822
1061
|
`utvärdera <post1> <post2> … <modell…>` kör varje ticket och modell i en EGEN
|
|
823
|
-
|
|
1062
|
+
`korning.mjs`-process, parallellt enligt `svep.mjs`: två tickets åt gången, alla
|
|
1063
|
+
modeller för en ticket samtidigt, och nästa ticket startar när en ticket är
|
|
1064
|
+
helt klar (steg 4). Raden `svep.mjs` kör per varv:
|
|
824
1065
|
|
|
825
1066
|
```
|
|
826
|
-
|
|
1067
|
+
node <skillkatalog>/scripts/korning.mjs --katalog <k<N>> --exp <experiments/<slug>> --repo-rot <abs> --request-id <gid> --modell <modell>
|
|
827
1068
|
```
|
|
828
1069
|
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
1070
|
+
Underlaget läses från disk av `korning.mjs`; ingenting går via stdin till
|
|
1071
|
+
orkestreringen, bara till agentprocesserna. Vilka rader varje agentprompt bär
|
|
1072
|
+
(ÖNSKEMÅL, KÄLLOR, REPO-ROT, DEPS, SPRÅK, RUBRIKER, ESKALERAD, REQUEST_ID) bor
|
|
1073
|
+
i scriptet och dess tester.
|
|
833
1074
|
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
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.
|
|
1075
|
+
Det finns ingen orkestratormodell: agenternas modeller styrs av definition plus
|
|
1076
|
+
`--model`-override och verifieras per steg mot `modelUsage` i råsvaret, aldrig
|
|
1077
|
+
av svansraden ensam.
|
|
840
1078
|
|
|
841
|
-
`--
|
|
842
|
-
|
|
1079
|
+
`--om` och `--hoppa-över` är svepets egna flaggor; `korning.mjs` frågar aldrig
|
|
1080
|
+
något och kan därför inte hänga. `--hoppa-över` är dessutom precis
|
|
1081
|
+
återupptagningens semantik, ett avbrutet svep som startas om plockar upp där
|
|
1082
|
+
det stannade i stället för att betala om för allt färdigt.
|
|
1083
|
+
|
|
1084
|
+
`--katalog` pekar ut den körningskatalog som `archive.mjs ny-korning`
|
|
1085
|
+
redan allokerat åt den ticketen och modellen. `korning.mjs` arkiverar
|
|
843
1086
|
bara dit, aldrig någon annanstans.
|
|
844
1087
|
|
|
845
|
-
Svepets loop är startaren och
|
|
846
|
-
|
|
847
|
-
`archive.mjs proveniens` mot körningskatalogen när processen är klar
|
|
1088
|
+
Svepets loop är startaren, och den heter `svep.mjs`: den bär startarens hela
|
|
1089
|
+
ansvar per rad (`ny-korning`, tidtagningen som skriver `matning.json`,
|
|
1090
|
+
`archive.mjs proveniens` mot körningskatalogen när processen är klar,
|
|
1091
|
+
modellverifieringen och status via `archive.mjs experiment`), se steg 4.
|
|
848
1092
|
|
|
849
|
-
- **En ticket
|
|
850
|
-
|
|
851
|
-
|
|
1093
|
+
- **En ticket, en modell = en `korning.mjs`-process; varje agentsteg är ett
|
|
1094
|
+
eget kontextfönster.** Allt tillstånd bor i arkivet på
|
|
1095
|
+
disk; `svep.mjs` skriver en rad per ticket och modell när den startar och
|
|
1096
|
+
när den slutar (status, väggtid, USD) och en sluttabell, och huvudsessionen
|
|
1097
|
+
samlar bara det. `/clear` mellan tickets behövs inte — processgränsen är
|
|
852
1098
|
motsvarigheten. Headless-körningen förutsätter att uppgiften kan köra utan
|
|
853
1099
|
interaktiva permission-frågor, vilket håller: den läser repot och skriver
|
|
854
|
-
enbart under `.haus/requests
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
1100
|
+
enbart under `.haus-workflow/requests/`. Asana-hämtningen gjordes redan i
|
|
1101
|
+
steg 1 av huvudkonversationen, som skrev `onskemal.md`, så `korning.mjs`
|
|
1102
|
+
behöver ingen MCP-kontakt alls.
|
|
1103
|
+
- **Kör vidare vid fel.** En ticket vars underlag saknas (`onskemal.md`,
|
|
1104
|
+
`kallmanifest.md` eller `experiment.json` med `request_id`) märks och hoppas
|
|
1105
|
+
över; en vars process kraschar blir `"ofärdig"` med orsak. Resten av svepet
|
|
1106
|
+
fortsätter, och `svep.mjs` avslutar med exit 1 när någon körning blev
|
|
1107
|
+
`"ofärdig"`, annars 0.
|
|
1108
|
+
- **Återupptagbart:** det gör `svep.mjs`: innan en körning startas
|
|
1109
|
+
kontrolleras arkivet, styrt av
|
|
859
1110
|
körningens `status` i `experiment.json`. `"klar"` och `"stopp"` hoppas
|
|
860
1111
|
över med en notis. `"ofärdig"` är avbruten data, inget resultat värt att
|
|
861
1112
|
skydda: den utlöser aldrig omkörningsfrågan, utan körs om automatiskt som
|
|
@@ -864,16 +1115,16 @@ runt `claude -p`-anropet och skriver `matning.json`, och den kör
|
|
|
864
1115
|
`"väntar på dom"` OMVÄRDERAS i stället för att hoppas över, det är den
|
|
865
1116
|
enda platsen som är aktören för den statusen: kör `archive.mjs sparr` på
|
|
866
1117
|
körningskatalogen. Exit 0 betyder att domen är fälld: sätt körningens
|
|
867
|
-
status till `"klar"` och fortsätt där den
|
|
868
|
-
separat när alla körningar för posten är
|
|
869
|
-
den fortfarande väntar: notera det och gå vidare
|
|
870
|
-
`döm` fäller domen men rör aldrig `experiment.json` (se
|
|
871
|
-
bara genom att `utvärdera` körs igen för samma post som
|
|
872
|
-
uppdateras. Omkörningsfrågan (se `utvärdera` ovan) gäller alltså bara
|
|
1118
|
+
status till `"klar"` via `archive.mjs experiment` och fortsätt där den
|
|
1119
|
+
stannade (rapporten kan köras separat när alla körningar för posten är
|
|
1120
|
+
klara). Exit 1 betyder att den fortfarande väntar: notera det och gå vidare
|
|
1121
|
+
till nästa varv. `döm` fäller domen men rör aldrig `experiment.json` (se
|
|
1122
|
+
`döm`), det är bara genom att `utvärdera` körs igen för samma post som
|
|
1123
|
+
statusen uppdateras. Omkörningsfrågan (se `utvärdera` ovan) gäller alltså bara
|
|
873
1124
|
`"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
|
|
875
|
-
risken att lappa ihop halva resultat. Ett svep över många tickets
|
|
876
|
-
därmed fortsätta i en senare session utan onödiga omkörningar.
|
|
1125
|
+
en ofärdig körning har inget att skydda. Körningar är billiga
|
|
1126
|
+
relativt risken att lappa ihop halva resultat. Ett svep över många tickets
|
|
1127
|
+
kan därmed fortsätta i en senare session utan onödiga omkörningar.
|
|
877
1128
|
|
|
878
1129
|
### Sammanställning
|
|
879
1130
|
|
|
@@ -923,8 +1174,11 @@ människans, gjord på erfarenhet av systemet. Rapporten visar spridningen.
|
|
|
923
1174
|
|
|
924
1175
|
## Mekaniska script: `scripts/`
|
|
925
1176
|
|
|
926
|
-
|
|
927
|
-
`
|
|
1177
|
+
Tolv deterministiska script bor i katalogen: de fem kontrollerna nedan,
|
|
1178
|
+
`kontroll.mjs` som kör scorerns kontrollkedja i en process,
|
|
1179
|
+
`archive.mjs` som äger arkivets kataloger, spärrar och `experiment.json`,
|
|
1180
|
+
`svep.mjs` som är utvärderas startare,
|
|
1181
|
+
`korning.mjs` som är utvärderas inre process, `report.mjs` som
|
|
928
1182
|
renderar modellrapporten (se `utvärdera rapport`), `lib.mjs` med de delade
|
|
929
1183
|
byggstenarna och `ref-hash.mjs` för stabil hashning. Kontrollerna ersätter
|
|
930
1184
|
modellkörningar där kontrollen är ren form,
|
|
@@ -935,7 +1189,17 @@ referensfiler vars regler det speglar och VARNAR när en katalogbump ändrat dem
|
|
|
935
1189
|
- `scripts/precheck.mjs <arkivkatalog> [--impact]` — formkontroll FÖRE dyra
|
|
936
1190
|
dispatcher: rubriker, exakt ett specblock, 2–5 punkter, förbjuden vokabulär,
|
|
937
1191
|
granskarblocksrader, state.json-fält. Skiljer på BRISTER (exit 1, stoppar)
|
|
938
|
-
och VARNING (heuristik — visas, stoppar inte).
|
|
1192
|
+
och VARNING (heuristik — visas, stoppar inte). Rubrikerna matchas via
|
|
1193
|
+
aliastabellen i `lib.mjs` på svenska eller engelska; rubriker ur båda
|
|
1194
|
+
språken i samma spec är en BRIST. Kandidatformen känns igen på markörraden
|
|
1195
|
+
(`**Koncept-kandidat**`/`**Diagnos-kandidat**`, eller de engelska
|
|
1196
|
+
motsvarigheterna) och skrivs som `KANDIDAT: KONCEPT` eller
|
|
1197
|
+
`KANDIDAT: DIAGNOS` på stdout, alltid, även vid exit 1; en kandidat med en
|
|
1198
|
+
Lösning är en BRIST. Med `--impact` läses etiketten på analysens rad
|
|
1199
|
+
`**Avvikelse mot specen:**` och skrivs som `AVVIKELSE: ingen`,
|
|
1200
|
+
`AVVIKELSE: precisering` eller `AVVIKELSE: motsägelse`; en rad utan
|
|
1201
|
+
etikett är en BRIST. Orkestratorn läser kandidat och avvikelse ur de
|
|
1202
|
+
raderna, aldrig ur filerna själv.
|
|
939
1203
|
- `scripts/resolve-anchors.mjs <run.json> <spec.md> [impact.md]` — löser
|
|
940
1204
|
beläggsankare (`belagg_ankare`/`ankare`) till ordagranna källblock, körs
|
|
941
1205
|
FÖRE contract-check. Exit 0 = allt löst (eller inga ankare i filen), 1 =
|
|
@@ -950,6 +1214,16 @@ referensfiler vars regler det speglar och VARNAR när en katalogbump ändrat dem
|
|
|
950
1214
|
INPUT_SAKNAS kräver saknas-lista i stället för frågerader. Ett olöst ankare
|
|
951
1215
|
(belägg saknas trots `belagg_ankare`, eller `ankare` utan `citat`) är
|
|
952
1216
|
dispatcherns fel, inte agentens: exit 2 med hänvisning till resolve-anchors.mjs.
|
|
1217
|
+
Stegschemat: varje `bracket.steps[i]` (även per alternativ) är exakt
|
|
1218
|
+
`{anchor, relation, grund}` med `relation` ur `storre`, `mindre`, `lika`;
|
|
1219
|
+
egna nycklar och tomma grunder är BROTT. Motsägelsegrinden: ges `impact.md`
|
|
1220
|
+
och analysens `**Avvikelse mot specen:**` bär `motsägelse` är varje annat
|
|
1221
|
+
utfall än TILLBAKA_TILL_SPEC ett BROTT. Prövar dessutom inringningens
|
|
1222
|
+
konsistens (golv före tak, between angränsande och inuti golv–tak, poäng
|
|
1223
|
+
mellan between-paret, relation mot poäng; poäng PÅ ett ankare trots
|
|
1224
|
+
storre/mindre är VARNING bara vid avrundningskollaps), att `type` är en av
|
|
1225
|
+
skalans fem typer, och undantar svartlistade ord som står i specen
|
|
1226
|
+
(ADR-0115).
|
|
953
1227
|
- `scripts/check-lasta.mjs "<LÄSTA-innehåll>" <spec.md> <impact.md>` —
|
|
954
1228
|
kontrollerar scorerns läs-scope: LÄSTA-raden ska bära underlagens två
|
|
955
1229
|
sökvägar och får därutöver bara bära filer under skillens egen katalog.
|
|
@@ -960,8 +1234,75 @@ referensfiler vars regler det speglar och VARNAR när en katalogbump ändrat dem
|
|
|
960
1234
|
`LIKA_TOLERANS` (poängskillnad ≤ 0,5 med samma outcome, oavsett confidence,
|
|
961
1235
|
och ankarband som överlappar eller angränsar; exit 0, verdiktraden pekar ut
|
|
962
1236
|
körningen med högst poäng) eller `OLIKA` + diffrader; exit 0/1, exit 2 =
|
|
963
|
-
ojämförbara körningar (dispatcherfel, aldrig LIKA).
|
|
964
|
-
|
|
1237
|
+
ojämförbara körningar (dispatcherfel, aldrig LIKA). Diffar även de inre
|
|
1238
|
+
stegen: samma ankare i `bracket.steps` med `storre` i ena körningen och
|
|
1239
|
+
`mindre` i den andra ger diffraden
|
|
1240
|
+
`bracket.steps[A<n>].relation: "mindre" ↔ "storre"`, en hård diff som
|
|
1241
|
+
aldrig faller under toleransen; golv- och takankare i någon av körningarna
|
|
1242
|
+
undantas, de flippar av konstruktion när banden angränsar. Scriptet kräver
|
|
1243
|
+
mode `pricing`; guard-jämförelser är en medveten utbyggnad i guard-steget.
|
|
1244
|
+
Angränsning avgörs av skalans ordning (lib.mjs ANKARE, A17 mellan A12 och
|
|
1245
|
+
A13), och utöver poäng och ankare diffas `type` (toleransrad), antalet
|
|
1246
|
+
`conditions` (hård diff) och `alternatives` per label (ADR-0115).
|
|
1247
|
+
- `scripts/archive.mjs <kommando> <katalog> [flaggor]`: arkivets mekanik
|
|
1248
|
+
(fullständig lista i scriptets huvud): `add-run`, `next-n`, `sparr`,
|
|
1249
|
+
`utslag`, `set-status`, `kalibrering`, `ny-korning`, `proveniens`, samt
|
|
1250
|
+
`stopp <katalog> --utfall KONCEPT|DIAGNOS|TILLBAKA_TILL_SPEC --kalla spec.md|impact.md`
|
|
1251
|
+
(skriver `state.stopp` efter att ha kontrollerat att källan bär utfallet;
|
|
1252
|
+
`--kalla impact.md` sätter status `assessed`, `--kalla spec.md` rör inte
|
|
1253
|
+
status), `respec <katalog>` (lägger undan `impact.md` som
|
|
1254
|
+
`impact-superseded-<datum>.md`, återställer status `spec_draft`,
|
|
1255
|
+
`approval`, `granskarutslag` och `stopp`, rör aldrig `runs[]`) och
|
|
1256
|
+
`bluf <katalog>` (markdown-tabellen `| post | poäng | utfall | konfidens | anm |`
|
|
1257
|
+
över katalogen och dess `del-N/` rekursivt, bunt-roten som
|
|
1258
|
+
`bunt (N delar)`; värdena ur filerna, aldrig ur prosa). `add-run` läser
|
|
1259
|
+
`effort:` ur agentdefinitionen när `--effort` utelämnas och kanoniserar
|
|
1260
|
+
`--model`; `set-status priced` vägrar när `stopp` är satt.
|
|
1261
|
+
`experiment <experimentkatalog> [--satt nyckel=värde]... [--variant <modell>]... [--korning <modell>/k<N> --status <klar|ofärdig|stopp|väntar på dom> [--orsak <text>]]`
|
|
1262
|
+
är den ENDA skrivaren av `experiment.json` (se `utvärdera` steg 1): låst
|
|
1263
|
+
läs-modifiera-skriv med atomisk skrivning, katalog och fil skapas om de
|
|
1264
|
+
saknas. `--satt` skriver toppnivåfält append-only (samma värde är no-op,
|
|
1265
|
+
ett annat värde är exit 2; `eskalerad` tolkas som boolean), `--variant` är
|
|
1266
|
+
UNION med bevarad ordning, och `--korning` kräver `--status` ur de fyra
|
|
1267
|
+
statusliteralerna, rör ingen annan körning och kräver att katalogen
|
|
1268
|
+
`<modell>/k<N>` finns. Exit 0 ok, 2 användnings- eller tillståndsfel.
|
|
1269
|
+
- `scripts/svep.mjs --repo-rot <abs> --konto <namn> --modell <m>... --exp experiments/<slug>... [--tickets-parallellt 2] [--om | --hoppa-över]`:
|
|
1270
|
+
utvärderas startare (se `utvärdera` steg 4 och Batch). Kör två tickets åt
|
|
1271
|
+
gången med alla modeller per ticket samtidigt, nästa ticket när en är helt
|
|
1272
|
+
klar, och gör per varv `ny-korning`, starten av `korning.mjs`,
|
|
1273
|
+
`stderr.log`, `matning.json`, `proveniens`,
|
|
1274
|
+
modellverifiering mot `modelUsage` och status via `archive.mjs experiment`.
|
|
1275
|
+
Återupptar ur `experiment.json`: `klar` och `stopp` hoppas utan `--om`,
|
|
1276
|
+
`väntar på dom` prövas med `sparr`, `ofärdig` körs om. En `--exp` utan
|
|
1277
|
+
`onskemal.md`, `kallmanifest.md` eller `experiment.json` med `request_id` märks
|
|
1278
|
+
och hoppas över. Exit 0 när ingen körning blev `ofärdig`, 1 annars, 2 vid
|
|
1279
|
+
användningsfel.
|
|
1280
|
+
- `scripts/korning.mjs --katalog <abs k<N>> --exp <abs experimentkatalog> --repo-rot <abs> --request-id <gid eller slug> --modell <modell|default> [--claude <kommando>] [--delar-parallellt 2]`:
|
|
1281
|
+
utvärderas inre process (se `utvärdera` steg 4), ett script utan
|
|
1282
|
+
modellturer. Bygger prompterna ur `onskemal.md`, `kallmanifest.md` och
|
|
1283
|
+
`experiment.json`, där `sprak` är OBLIGATORISK: saknas den skrivs en
|
|
1284
|
+
instruktion på stderr och scriptet avslutar med exit 2 innan någon prompt
|
|
1285
|
+
byggs (ADR-0114). Varje agentsteg är en egen `claude -p --agent`-process med
|
|
1286
|
+
råsvaret under `k<N>/steg/`, och kontrollerna (precheck, `kontroll.mjs`,
|
|
1287
|
+
compare-scores) plus arkiveringen (`archive.mjs`) är scriptanrop.
|
|
1288
|
+
Buntens delar körs två åt gången och scorerns två körningar samtidigt;
|
|
1289
|
+
`DELA_UPP` körs inte autonomt i v1 utan ger status `stopp` med orsak.
|
|
1290
|
+
`korning.json` är summan över stegen (`korningsmotor`, `steg`,
|
|
1291
|
+
`modellverifiering` plus rapportens vanliga nycklar). Exit 0 när körningen
|
|
1292
|
+
gick igenom, 1 när minst en del blev ofärdig, 2 vid användningsfel.
|
|
1293
|
+
- `scripts/kontroll.mjs <svar.txt> <spec.md> <impact.md> --expect-id <id> --ut <ren.json> [--fixa-kundtext] [--claude <kommando>] [--fix-modell sonnet] [--fix-fil <rå.json>]`:
|
|
1294
|
+
scorerns kontrollkedja i EN process (se `bedöm` steg 5): svansrader,
|
|
1295
|
+
JSON-extraktion, deterministiska reparationer, sedan check-lasta,
|
|
1296
|
+
resolve-anchors och contract-check i EN process. Reparerar det dispatchern
|
|
1297
|
+
redan vet: `request_id`, versaler och gemener på `outcome`, `mode`,
|
|
1298
|
+
`confidence` och `bracket.steps[].relation`, sträng till tal på `score`, och
|
|
1299
|
+
LÄSTA-radens sökvägsform. Reparationerna rör aldrig poäng, utfall eller
|
|
1300
|
+
belägg, och varje reparation skrivs som en `REPARERAT:`-rad som anroparen
|
|
1301
|
+
bokför i runs-radens `note`. `--fixa-kundtext` skriver om ett
|
|
1302
|
+
protokollterm-brott i ett rent kundtextfält med en billig modell i stället
|
|
1303
|
+
för att kosta en hel scorerkörning, högst en runda. stdout bär `MODELL:`,
|
|
1304
|
+
`LÄSTA:`, ev. `AVVIKELSE:`, `REPARERAT:`-rader och sist verdiktet. Exit 0 =
|
|
1305
|
+
kedjan håller, 1 = BROTT (omdispatch enligt ADR-0092), 2 = användningsfel.
|
|
965
1306
|
|
|
966
1307
|
Kontrollerna bedömer aldrig innehåll och returnerar aldrig protokollutfall —
|
|
967
1308
|
en post som passerar kan fortfarande stoppas av protokollen själva, och det är
|
|
@@ -983,13 +1324,35 @@ aldrig vidare som om kontrollen passerat.
|
|
|
983
1324
|
<manifest med absoluta sökvägar, eller "inga — allt blir antaganden">
|
|
984
1325
|
|
|
985
1326
|
REPO-ROT: <absolut sökväg eller "saknas">
|
|
1327
|
+
DEPS: <installerade | saknas>
|
|
1328
|
+
SPRÅK: <svenska | engelska>
|
|
1329
|
+
RUBRIKER:
|
|
1330
|
+
**Problem**
|
|
1331
|
+
**Lösning**
|
|
1332
|
+
**När det är klart**
|
|
1333
|
+
**Ingår inte**
|
|
1334
|
+
**Utseende**
|
|
1335
|
+
**Kräver**
|
|
1336
|
+
**Villkor**
|
|
986
1337
|
ESKALERAD: <ja|nej>
|
|
987
1338
|
```
|
|
988
1339
|
|
|
1340
|
+
`RUBRIKER:` är skelettet på specens språk, literalerna ordagrant. Det
|
|
1341
|
+
svenska står ovan; vid `SPRÅK: engelska` tas de sju raderna ur
|
|
1342
|
+
rubriktabellen i `request-write-spec/references/specformat.md`
|
|
1343
|
+
(Problem, Solution, Done when, Not included, Appearance, Requires,
|
|
1344
|
+
Conditions). Fotnot: en kandidat ersätter Lösning och När det är klart med
|
|
1345
|
+
markörraden (`**Koncept-kandidat**` eller `**Diagnos-kandidat**`, på
|
|
1346
|
+
engelska `**Concept candidate**` eller `**Diagnosis candidate**`), det
|
|
1347
|
+
avgör specifiern själv enligt skillen.
|
|
1348
|
+
|
|
989
1349
|
`request-assessor`:
|
|
990
1350
|
|
|
991
1351
|
```
|
|
992
1352
|
REPO-ROT: <absolut sökväg>
|
|
1353
|
+
DEPS: <installerade | saknas>
|
|
1354
|
+
KÄLLOR:
|
|
1355
|
+
<kallmanifest.md ordagrant, eller "inga">
|
|
993
1356
|
|
|
994
1357
|
SPEC (godkänd):
|
|
995
1358
|
<spec.md bytetroget>
|