@haus-tech/haus-workflow 5.0.1 → 5.2.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.
@@ -87,7 +87,7 @@ Testfrågan: **skulle användaren märka skillnad mellan alternativen?**
87
87
 
88
88
  **Nej** — delad komponent eller speciallösning, vilket mönster som återanvänds, var koden hamnar, hur något lagras när beteendet blir detsamma. Det här är ditt beslut. Välj det som är bäst för systemet på sikt och redovisa varför.
89
89
 
90
- **Ja** — funktionen beter sig olika, något ingår eller inte, användaren ser eller får olika saker. Då är det inte ditt val. Det är en fråga specen skulle ha besvarat, och den ska tillbaka dit. Skriv ut den i granskarblocket under _Avvikelse mot specen_, och beskriv vad som är obesvarat — välj inte "det troliga" och gå vidare.
90
+ **Ja** — funktionen beter sig olika, något ingår eller inte, användaren ser eller får olika saker. Då är det inte ditt val. Det är en fråga specen skulle ha besvarat, och den ska tillbaka dit. Skriv ut valet i granskarblocket under _Obesvarade utfallsval_ med alternativen. Etiketten på _Avvikelse mot specen_ blir `precisering` så länge minst ett listat alternativ levererar specens Problem; `motsägelse` bara när inget gör det.
91
91
 
92
92
  Design, utseende, flöde och UX hör alltid till den andra kategorin.
93
93
 
@@ -114,10 +114,49 @@ Analysen som ett dokument, en sida. Sedan ett kort block till granskaren:
114
114
  ## Till granskaren
115
115
 
116
116
  **Ej verifierat:** [vad du inte kunnat belägga i koden, och varför]
117
- **Avvikelse mot specen:** [om koden säger något annat än specen förutsätter]
118
- **Obesvarade utfallsval:** [ett stycke per val — se nedan]
117
+ **Avvikelse mot specen:** <ingen | precisering | motsägelse>. [fritext: vad koden säger och vad specen förutsätter]
118
+ **Obesvarade utfallsval:** [inga, eller en listpunkt per val ("- "), se nedan]
119
119
  ```
120
120
 
121
+ ### Avvikelse mot specen
122
+
123
+ Raden börjar ALLTID med en av tre etiketter, som första ord efter kolonet.
124
+ Formkontrollen läser etiketten, och poängsättaren agerar på den. En rad med
125
+ bara fritext ("bör tillbaka till specen") är osynlig för båda: det var så två
126
+ motsägelser i samma ärende prissattes i stället för att stoppas.
127
+
128
+ - `ingen`: koden stämmer med det specen förutsätter.
129
+ - `precisering`: specen lämnar något öppet som koden fyller i utan att specen
130
+ blir fel, till exempel exakt var ett fält hamnar i en befintlig vy. Skriv
131
+ vad du preciserat; det blir en förutsättning i förslaget, aldrig ett stopp.
132
+ - `motsägelse`: specen förutsätter något som inte stämmer i systemet, eller en
133
+ punkt går inte att leverera som den står. Posten går tillbaka till specen
134
+ utan poäng. Skriv vad som inte stämmer och var i koden det syns. Etiketten
135
+ får bara sättas när _Obesvarade utfallsval_ är `inga` eller när varje listat
136
+ alternativ är struket (se nedan). Listar du ett alternativ som löser
137
+ problemet är etiketten `precisering`, och poängsättarens fyrstegsregel
138
+ avgör. Formkontrollen fäller `motsägelse` med ostrukna alternativ.
139
+
140
+ Efter etiketten följer fritexten som förut. Flera avvikelser: etiketten är den
141
+ allvarligaste av dem (motsägelse väger över precisering), och varje avvikelse
142
+ får en egen mening.
143
+
144
+ ### Kundens språk
145
+
146
+ Prompten bär `SPRÅK: svenska | engelska`, kundens språk. Analysen är
147
+ Haus-intern, men delar av den går vidare till kunden genom poängsättaren: det
148
+ preciserade på avvikelseraden blir en förutsättning i förslaget, och
149
+ alternativen under _Obesvarade utfallsval_ blir kundens alternativ. Namnge
150
+ dem i kundens språk ur promptens `SPRÅK:`-rad; i en fristående körning utan
151
+ raden är det specens språk.
152
+
153
+ ### Beroenden i arbetskopian
154
+
155
+ Prompten bär `DEPS: installerade | saknas`. Vid `saknas` finns inga
156
+ installerade paket i arbetskopian: verifiera aldrig genom att installera
157
+ något, och redovisa det du inte kunnat belägga i paketen (exporter, versioner,
158
+ API-ytor) under _Ej verifierat_ med orsaken "beroenden ej installerade".
159
+
121
160
  ### Obesvarade utfallsval
122
161
 
123
162
  Ett utfallsval som specen lämnat öppet skrivs ut med tre saker, och alla tre behövs:
@@ -132,12 +171,27 @@ Ett utfallsval som specen lämnat öppet skrivs ut med tre saker, och alla tre b
132
171
  kunna beskriva systemet. Skriv "beskriven utifrån X", aldrig "vi väljer X" — valet
133
172
  är inte ditt.
134
173
 
174
+ Varje val är en egen listpunkt på översta nivån som börjar med "- ", och de tre
175
+ delarna ovan (alternativen, om de skiljer sig i vad som måste byggas, vilket
176
+ alternativet analysen är skriven utifrån) skrivs på indenterade underrader
177
+ under den punkten, inte som egna listpunkter. Formkontrollen räknar bara
178
+ listpunkter på kolumn 0; en underrad räknas inte som ett eget alternativ.
179
+ Alternativ i löptext ("(a) text i bilden, (b) egen komponent") räknas inte
180
+ alls: formkontrollen fäller `motsägelse` med sådan prosa i avsnittet som en
181
+ brist och varnar vid `precisering`, så skriv listan eller skriv `inga`, aldrig
182
+ en uppräkning i en mening.
183
+
184
+ **Struket alternativ.** Ett alternativ som inte löser specens _Problem_ raderas inte,
185
+ det stryks: den översta listpunkten (samma nivå som alternativets "- ") börjar med
186
+ `struket:` (engelska: `struck:`) följt av skälet, prefixet flyttas aldrig ner till en
187
+ underrad. Så syns det att alternativet prövats.
188
+
135
189
  Skälet till punkt 2: den som poängsätter posten har inte repot och kan inte se om
136
190
  alternativen kostar olika. Utan din rad måste den anta det värsta och stoppa posten,
137
191
  även när båda vägarna är samma arbete. Det är den vanligaste orsaken till att en post
138
192
  studsar tillbaka till specen i onödan.
139
193
 
140
- Sista raden är den viktigaste. Förutsätter specen något som inte stämmer i systemet är det ett fel som ska tillbaka till specen, inte något som ska poängsättas.
194
+ Avvikelseraden är den viktigaste. Förutsätter specen något som inte stämmer i systemet är det ett fel som ska tillbaka till specen, inte något som ska poängsättas, och etiketten `motsägelse` är det som gör att det faktiskt händer.
141
195
 
142
196
  ## Vad du aldrig gör
143
197
 
@@ -35,7 +35,7 @@ Poäng sätts bara på en post som går att bygga. Fem utfall stoppar poängsät
35
35
  | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
36
36
  | `KONCEPT` | Formen är okänd — designfråga, oavgjort vägval, flera lösningsvägar utan beslut | Egen post som levererar ett förslag och en poäng på bygget |
37
37
  | `DIAGNOS` | Orsaken är okänd och går att undersöka. Gäller framför allt fel där ingen vet varför något är trasigt | Tidsboxad undersökning som levererar besked och en poängsatt åtgärd |
38
- | `TILLBAKA_TILL_SPEC` | Specen lämnar ett utfallsval obesvarat **och valet ändrar arbetsmängden** | Specen kompletteras, sedan ny körning |
38
+ | `TILLBAKA_TILL_SPEC` | Påverkansanalysen anger `motsägelse` under _Avvikelse mot specen_ (specen förutsätter något som inte stämmer), eller inget alternativ löser problemet (steg 2 nedan) | Specen kompletteras, sedan ny körning |
39
39
  | `DELA_UPP` | Posten går inte att ringa in på egen hand — se nedan | Ny analysrunda som pekar ut delarna, sedan en körning per del |
40
40
  | `ESKALERA` | Bedömningen kräver en människa: ett prisbärande avgörande som inte får vila på en gissning, och som varken är en delningsfråga (`DELA_UPP`) eller ett hål i underlaget (`INPUT_SAKNAS`) | Posten visas för en människa; skriv i `notes` vilken fråga och varför |
41
41
 
@@ -62,6 +62,26 @@ den `OVER_SKALAN` och offereras — den delas inte vidare.
62
62
  **En post som redan har poängsatta delar poängsätts aldrig som helhet.** Föräldern bär
63
63
  summan av sina delar, inte en egen siffra.
64
64
 
65
+ ### Motsägelse först
66
+
67
+ Påverkansanalysens granskarblock börjar raden _Avvikelse mot specen_ med en
68
+ etikett: `ingen`, `precisering` eller `motsägelse`. Läs den innan något annat.
69
+
70
+ `motsägelse` betyder att specen förutsätter något som inte stämmer i systemet,
71
+ eller att en punkt inte går att leverera som den står. Etiketten är satt bara
72
+ när analysen inte listar något ostruket alternativ (ADR-0117); formkontrollen
73
+ har redan fällt en analys som bär `motsägelse` tillsammans med alternativ, så
74
+ du möter aldrig det fallet. Då är utfallet
75
+ `TILLBAKA_TILL_SPEC`, utan undantag och före fyrstegsregeln nedan: en poäng på
76
+ en spec som motsäger koden prissätter något som inte går att bygga. Skriv i
77
+ `customer_rationale`, i kundens språk, vad som behöver avgöras. Kontrakts-
78
+ kontrollen fäller varje annat utfall när analysen bär `motsägelse`, och
79
+ orkestratorn dispatchar dig normalt inte alls i det läget.
80
+
81
+ `precisering` är ingen avvikelse att stoppa på: analysen har fyllt i något
82
+ specen lämnade öppet utan att specen blev fel. Det preciserade går in i
83
+ `assumptions_stated` som en förutsättning. `ingen` kräver inget.
84
+
65
85
  ### Obesvarade utfallsval
66
86
 
67
87
  Påverkansanalysens granskarblock listar under _Obesvarade utfallsval_ de val specen
@@ -119,10 +139,14 @@ mellan två körningar. Ringa in i stället, i fyra steg. Alla fyra redovisas i
119
139
  Får du inget golv: posten är mindre än A1 och får A1:s poäng. Skalans nedre ände är
120
140
  ändå dominerad av den fasta processavgiften.
121
141
 
122
- Får du inget tak: posten är större än skalans högsta referensuppdrag. Sätt då `DELA_UPP`
123
- och ingen poäng, så att posten först prövas i delar. Är detta redan en del av en delad
124
- post sätter du i stället `OVER_SKALAN` — underlaget för den nivån är för tunt för att
125
- jämföra mot, och posten ska offereras separat.
142
+ Får du inget tak: posten är större än skalans högsta referensuppdrag. Du måste ha
143
+ jämfört mot skalans översta ankare (A16) och redovisat det i `bracket.steps` innan du
144
+ säger det; ett "inget tak" utan den jämförelsen fälls av kontraktskontrollen. Sätt då
145
+ `DELA_UPP` och ingen poäng, så att posten först prövas i delar. Är posten redan en
146
+ split-del (`split.part` i underlaget, en tidigare `DELA_UPP`) sätter du i stället
147
+ `OVER_SKALAN`: underlaget för den nivån är för tunt att jämföra mot, och posten
148
+ offereras separat. En buntdel (`bundle.part`, flera specar ur samma önskemål) är inte
149
+ en split-del; på en buntdel utan tak är utfallet `DELA_UPP`.
126
150
 
127
151
  **Steg 3 — snäva in.** Gå igenom referensuppdragen mellan golv och tak. För varje: är
128
152
  posten större eller mindre, och på vilken grund? Fortsätt tills du har två
@@ -153,8 +177,10 @@ repot saknar testsvit. Räkna bara det manuella arbete som återstår när en fu
153
177
  testsvit gjort sitt: det som kräver en människa av sin natur, alltså kontroll mot en
154
178
  extern tjänsts testläge, visuell granskning, eller genomgång på flera enheter eller i
155
179
  flera miljöer. Saknas testsviten är det inte en rabatt: täckningen byggs som en egen
156
- post före ändringen och poängsätts för sig. Skriv en rad under `notes` om vilken yta
157
- som saknar täckning, så att den posten går att skapa.
180
+ post före ändringen och poängsätts för sig. Fyll då `coverage_post` med `yta` (den
181
+ yta som saknar täckning, i kundens språk) och `omfattning` (en mening om vad
182
+ täckningsposten bygger). Fältet är det som gör att posten kan skapas, en not i
183
+ `notes` räcker inte. Utelämna fältet helt när antagandet inte görs.
158
184
 
159
185
  **Vad som händer om det blir fel.** Felaktig betalning, felaktig åtkomst till någon
160
186
  annans uppgifter, förlorad data eller bruten befintlig funktion väger tungt. Fel text
@@ -179,6 +205,10 @@ uppdrag av en typ som saknas i skalan poängsätts mot de närmaste i storlek, i
179
205
  någon påhittad justering. Skriv ut vilken typ du bedömt posten som — den loggas för att
180
206
  kunna mäta i efterhand om någon typ hamnar systematiskt fel.
181
207
 
208
+ `type` är ett av översiktstabellens fem värden, ordagrant: Kundvänd funktion, Underhåll,
209
+ Teknisk uppsättning, Integration, Internt verktyg. Saknar posten en självklar typ, välj
210
+ den närmaste och skriv resonemanget under `notes`, aldrig i själva värdet.
211
+
182
212
  ## Grindläget
183
213
 
184
214
  Körs skillen på en fullständig implementationsplan efter kundens godkännande, sätt
@@ -205,7 +235,7 @@ Bygger fullplanen ett annat vägval än det som såldes är det en händelse att
205
235
  "floor": { "anchor": "", "score": null, "why": "" },
206
236
  "ceiling": { "anchor": "", "score": null, "why": "" },
207
237
  "between": ["", ""],
208
- "steps": []
238
+ "steps": [{ "anchor": "A12", "relation": "storre | mindre | lika", "grund": "" }]
209
239
  },
210
240
  "drivers": [],
211
241
  "confidence": "hog | medel | lag",
@@ -214,6 +244,7 @@ Bygger fullplanen ett annat vägval än det som såldes är det en händelse att
214
244
  "alternatives": [],
215
245
  "dependencies": [],
216
246
  "notes": [],
247
+ "coverage_post": { "yta": "…", "omfattning": "…" },
217
248
  "customer_rationale": "",
218
249
  "guard_diff": []
219
250
  }
@@ -222,9 +253,13 @@ Bygger fullplanen ett annat vägval än det som såldes är det en händelse att
222
253
  `score` sätts bara när `outcome` är `POANG`, och alltid på skalans upplösning: steg om
223
254
  0,25 under 3 poäng, hela poäng från 3 och uppåt.
224
255
 
225
- `bracket.steps` är jämförelserna från steg 3, en per referensuppdrag du vägde mot, var
226
- och en med ankarets id, om posten är större eller mindre, och på vilken grund. Det är
227
- det som gör poängen granskbar. En poäng utan inringning är inte ett giltigt utfall.
256
+ `bracket.steps` är jämförelserna från steg 3, en per referensuppdrag du vägde mot. Varje
257
+ steg är ett objekt med exakt tre nycklar: `anchor` (ankarets id, `A12`), `relation`
258
+ (`storre` om posten är större än ankaret, `mindre` om den är mindre, `lika` om den är
259
+ jämbördig; ASCII, samma stil som `hog/medel/lag`) och `grund` (på vilken grund, en eller
260
+ två meningar). Inga andra nycklar, ingen poäng i steget: ankarets poäng står i skalan.
261
+ Det är det som gör poängen granskbar, och det är stegen driftvakten jämför mellan två
262
+ körningar. En poäng utan inringning är inte ett giltigt utfall.
228
263
 
229
264
  `drivers` är de två eller tre faktorer som mest avgjorde placeringen. Varje driver är
230
265
  ett objekt: `pastaende` (faktorn med dina ord, utan citattecken) och `ankare`
@@ -246,6 +281,11 @@ hit och ska utelämnas helt. Är listan tom fanns bara en väg som löser proble
246
281
  `notes` är iakttagelser som inte hör till poängen men som någon bör känna till, till
247
282
  exempel att ett repo saknar testsvit.
248
283
 
284
+ `coverage_post` är valfritt: bara när repot saknar den täckning skalan förutsätter
285
+ (se "Vad du jämför på"). `yta` är den yta som saknar täckning, i kundens språk;
286
+ `omfattning` är en mening om vad täckningsposten bygger. Utelämna fältet helt när
287
+ antagandet inte görs.
288
+
249
289
  **Ett antagande som analysen flaggat som overifierat ska alltid ut.** Går det att
250
290
  undersöka hör det till `notes` med hur det undersöks. Går det inte att undersöka blir
251
291
  det ett villkor i `conditions`, formulerat som "bygger på att X; faller X tidigt
@@ -264,6 +304,12 @@ ser rimlig ut.
264
304
  hur skalan räknade. Nämn aldrig poäng, referensuppdrag, ankare eller skalan. Kunden ska
265
305
  kunna invända mot omfattningen, inte mot modellen.
266
306
 
307
+ **Kundens språk** är, överallt i den här skillen, det promptens `SPRÅK:`-rad anger
308
+ (`svenska` eller `engelska`); i en fristående körning utan raden är det specens språk.
309
+ Det gäller `customer_rationale`, `conditions`, `assumptions_stated`, `alternatives`
310
+ (`label` och `adds`) och `coverage_post.yta`. Kontrollen fäller kundtext på fel språk,
311
+ och en sådan post dispatchas om i sin helhet.
312
+
267
313
  Finns alternativ: beskriv dem sist, som egna vägar med var sitt pris. En mening var
268
314
  räcker — vad kunden får i stället, och vad som tillkommer. Priset räknas ur poängen
269
315
  någon annanstans; skriv aldrig ut poängen.
@@ -39,6 +39,9 @@ saknar tester i dag.
39
39
  Skälet är att alla sjutton referensuppdrag är satta som om en testsvit fanns. Jämförs en
40
40
  post mot dem på annan grund mäter den inte samma sak, och skalan slutar hålla ihop.
41
41
 
42
+ Saknar repot täckningen: sätt poängen som om den fanns och fyll `coverage_post` i
43
+ utfallet, så att täckningen blir en egen post före ändringen och poängsätts för sig.
44
+
42
45
  Saknas täckningen är det inte en rabatt. Den byggs då som en egen post före ändringen
43
46
  och poängsätts för sig. Räkna här bara det manuella arbete som återstår när testerna
44
47
  gjort sitt: kontroll mot en extern tjänsts testläge, visuell granskning, och genomgång
@@ -65,7 +65,7 @@ Hämta brädans sektioner. **En sektion:** ingen fråga, använd den. **Flera se
65
65
 
66
66
  Hämta fälten på båda brädorna och gå igenom tre saker:
67
67
 
68
- - **Finns fälten?** Kundbrädan behöver `Original request`, `Customer`, `Requested by` och kundstatusfältet. Samlingsbrädan behöver dessa plus `Offer status`, `Source`, `Request type`, `Funding`, `Score`, `Conditional classification`, `Decision`, `Decision reason`, `Spec iterations`, `Class iterations`.
68
+ - **Finns fälten?** Kundbrädan behöver `Original request`, `Customer`, `Requested by` och kundstatusfältet. Samlingsbrädan behöver dessa plus `Offer status`, `Source`, `Request type`, `Funding`, `Score`, `Has conditions`, `Decision`, `Decision reason`, `Spec iterations`, `Score iterations`.
69
69
  - **Är de delade fälten samma fält?** Jämför gid, inte namn. Två fält med samma namn och olika gid är en dubblett — de driftar isär omedelbart, och felet syns först hos kunden.
70
70
  - **Går alternativen att slå upp?** Normaliserat, enligt regeln ovan. Rapportera vilka som inte gick att matcha och vilka alternativ som faktiskt finns.
71
71
 
@@ -130,7 +130,7 @@ Domän-JSON till vänster, fältnamn till höger. Ingen annan skill får se hög
130
130
  | `customer_rationale` | beskrivningens `## Lösning och omfattning` | Låst efter `Decision`, se nedan |
131
131
  | `assumptions_stated` ej tom | beskrivningens `## Lösning och omfattning` | Kunden godkänner dem med priset |
132
132
  | `alternatives` ej tom | beskrivningens `## Lösning och omfattning` | Egna vägar med var sitt pris |
133
- | `conditions` ej tom | Conditional classification | se nedan |
133
+ | `conditions` ej tom | Has conditions | se nedan |
134
134
  | `decision` | Decision | Beställd · Ej beställd · Uppskjuten |
135
135
  | `decision_reason` | Decision reason | |
136
136
 
@@ -139,16 +139,15 @@ där kunden faktiskt läser den. Att skriva samma text på två ställen gav tv
139
139
  som kunde glida isär, och fältet fanns bara för att kunna filtrera på en text ingen
140
140
  filtrerar på. Fältet får ligga kvar i Asana med sina gamla värden som historik.
141
141
 
142
- **Två fältnamn är historiska.** `Class iterations` och `Conditional classification`
143
- döptes när modellen satte klasser i stället för poäng. Innehållet är oförändrat i sak —
144
- en varvräknare och en ja/nej-flagga för villkor — så de används vidare under sina gamla
145
- namn hellre än att data flyttas. Döps de om i Asana måste den här mappningen uppdateras
146
- samtidigt.
142
+ **Fältnamnen byttes 2026-09-08 (ADR-0121):** `Score iterations` hette `Class iterations`
143
+ och `Has conditions` hette `Conditional classification`. Innehållet är oförändrat i sak,
144
+ en räknare över poängsättningsvarv och en ja/nej-flagga för villkor. En bräda som
145
+ fortfarande bär de gamla namnen är inte uppdaterad: säg till i stället för att gissa.
147
146
 
148
147
  `Score` är ett taltfält. Skriv poängen som tal, inte som text, så att den går att
149
148
  sortera och summera i listvyer.
150
149
 
151
- `Conditional classification` är härledd: villkorslistan är tom eller inte. Sätt alltid ett värde när en poängsättning skrivs — aldrig tomt, eftersom tomt är reserverat för "ingen har poängsatt än". Bär fältet flera värden samtidigt är det felkonfigurerat som flerval; skriv ett värde och säg till.
150
+ `Has conditions` är härledd: villkorslistan är tom eller inte. Sätt alltid ett värde när en poängsättning skrivs — aldrig tomt, eftersom tomt är reserverat för "ingen har poängsatt än". Bär fältet flera värden samtidigt är det felkonfigurerat som flerval; skriv ett värde och säg till.
152
151
 
153
152
  Asana konverterar markdown till `html_notes`. Använd `html_notes` för beskrivningen, för subtaskarnas innehåll och för kommentarer, inte `notes`, annars tappas struktur — rubriker, kursiv text och de vågräta linjerna mellan sektionerna försvinner alla med `notes`.
154
153
 
@@ -217,7 +216,7 @@ körningen gjordes.
217
216
 
218
217
  Skälet: en poäng som stiger är en prishöjning. Sker den genom att beskrivningen skrivs om finns inget spår av vad kunden faktiskt godkände, och den fria exiten — modellens centrala kundlöfte — går inte att lösa ut, eftersom det inte längre går att visa vad som ändrats.
219
218
 
220
- Låset gäller beskrivningen och `Score`, som bär den poäng priset räknades ur. Det som är internt får alltid skrivas — subtaskarna (det är hela poängen med dem: de är löpnumrerade och ärver inte kundbrädan, så en poängsättning efter kundbeslut landar där som vanligt), `Conditional classification` och räknarna.
219
+ Låset gäller beskrivningen och `Score`, som bär den poäng priset räknades ur. Det som är internt får alltid skrivas — subtaskarna (det är hela poängen med dem: de är löpnumrerade och ärver inte kundbrädan, så en poängsättning efter kundbeslut landar där som vanligt), `Has conditions` och räknarna.
221
220
 
222
221
  ### Grindläget stöds inte
223
222
 
@@ -361,8 +360,8 @@ Kundbrädan bär bara det kunden ska se. Interna fält finns enbart på samlings
361
360
  | Bara samlingsbrädan | Delade, syns på båda |
362
361
  | ---------------------------------- | ------------------------------------------ |
363
362
  | Offer status · Source | Kundstatus |
364
- | Spec iterations · Class iterations | Original request · Customer · Requested by |
365
- | Conditional classification | Request type · Funding |
363
+ | Spec iterations · Score iterations | Original request · Customer · Requested by |
364
+ | Has conditions | Request type · Funding |
366
365
  | | Score · Decision · Decision reason |
367
366
 
368
367
  Ett delat fält är **samma** fält på båda brädorna. Finns två fält med samma namn och olika gid är det en dubblett, inte en delning — de driftar isär omedelbart och felet syns först när en kund tittar på något som inte uppdaterats. Upptäcker du en sådan: skriv inte till någon av dem, säg till.
@@ -428,7 +427,7 @@ Skälet: `Request status` är det enda i hela flödet en kund ser. Två fält so
428
427
 
429
428
  Feedback är en kommentar plus en flytt bakåt till närmaste AI-läge. Två regler:
430
429
 
431
- **Bumpa räknaren.** Bakåt till 📥 höjer `Spec iterations`. Bakåt till ✅ höjer `Class iterations` (fältets namn är historiskt; det räknar poängsättningsvarv). Läs nuvarande värde och skriv värdet plus ett — sätt aldrig ett absolut tal från minnet.
430
+ **Bumpa räknaren.** Bakåt till 📥 höjer `Spec iterations`. Bakåt till ✅ höjer `Score iterations` (räknar poängsättningsvarv). Läs nuvarande värde och skriv värdet plus ett — sätt aldrig ett absolut tal från minnet.
432
431
 
433
432
  **Ändrad spec ogiltigförklarar poängsättningen.** Går en post bakåt till 📥 ska den passera ⚖️ igen på vägen tillbaka. Skriv inte över `Score` med ett nytt värde utan att posten gjort den resan.
434
433
 
@@ -55,7 +55,7 @@ Missar du en sådan fråga blir den ett tyst val längre fram i kedjan, fattat a
55
55
 
56
56
  **En skärm.** Behöver specen skrollas innehåller den nästan alltid två beslut.
57
57
 
58
- **Kundens språk.** Specen läses av kunden. Inga interna termer (protokolltermer, repo-namn, "backlog-post"), ingen story-mall ("Som X vill jag Y"). Svenska om önskemålet är på svenska.
58
+ **Kundens språk.** Specen läses av kunden. Inga interna termer (protokolltermer, repo-namn, "backlog-post"), ingen story-mall ("Som X vill jag Y"). Specen skrivs på önskemålets språk, svenska eller engelska, och rubrikerna tas ur specformatets rubriktabell på samma språk som brödtexten, aldrig blandat. Granskarblocket är internt och alltid på svenska. Anger prompten `SPRÅK:` är det avgjort där.
59
59
 
60
60
  ## Normalfallet: en rubrik och en mening
61
61
 
@@ -68,6 +68,8 @@ Det är hela inputen. Ditt jobb är beredningen — att växa en spec ur den. En
68
68
 
69
69
  **Leta innan du antar.** Inventera vad sessionen ger dig tillgång till och använd det. Vilka källor som finns beror på uppdraget: i ett befintligt system är kodbasen bäst (finns vyn redan? vilket mönster används för liknande listor? vad heter begreppen i koden?), följt av tidigare specar och tickets för samma kund (hur har liknande poster lösts? vilka termer använder kunden — "skattning", "skift", "verksamhet"?). I ett nytt projekt finns ingen kodbas — då är briefen, offertunderlaget eller annat projektmaterial källan, och lösningen förankras i vad det materialet säger om målgrupp, flöden och befintliga system hos kunden. Det du hittar i källorna är inte antaganden — det är fakta, och de gör specen träffsäker på riktigt. Först när en fråga inte går att besvara ur det som finns blir den ett antagande i granskarblocket. Skriv gärna i granskarblocket _var_ du hämtat de viktigaste faktana ("mönstret finns i användarhanteringsvyn", "enligt briefen sid 2") — det låter granskaren skilja verifierat från gissat på en sekund.
70
70
 
71
+ **Leta efter det som redan finns innan du skriver Lösning.** Sök i källmanifestet (`KÄLLOR:`) och med Grep i repot efter en inbyggd funktion i plattformen eller ett redan installerat paket som gör det önskemålet ber om: en väljare, en meny, en export, en behörighetsmodell som redan finns. Redovisa fyndet i granskarblocket under _Vägval jag gjort_ eller _Prisavgörande öppet val_, även när du inte hittade något ("ingen inbyggd yta för X funnen i KÄLLOR eller repot"). Det du inte letat efter kan du inte välja bort medvetet, och ett omedvetet egenbygge är det dyraste valet specen kan göra åt kunden (se regeln under Output).
72
+
71
73
  Sedan gäller för själva skrivandet:
72
74
 
73
75
  **Härled problemet ur önskemålet.** "Kan själv lägga till" betyder att någon idag inte kan själv — det görs via Haus eller inte alls. Det är problemraden. Du behöver inte veta detaljerna; skriv den mest sannolika vardagen och redovisa den som antagande om du är osäker.
@@ -88,11 +90,11 @@ Tre situationer, tre olika hanteringar — och ingen av dem är att fråga:
88
90
 
89
91
  **Ett värde någon annan ska bestämma** (t.ex. "gräns vid 12, 18 eller 24 månader?"): gör värdet konfigurerbart i lösningen så att frågan upphör att vara en fråga. "Gränsen ändras utan nytt bygge" är en utfallspunkt; det exakta värdet är en inställning, inte ett spec-beslut.
90
92
 
91
- **Ett vägval som inte går att avgöra utan kunden** — designfrågor, UX-riktning, okänd felorsak, eller ett val som påverkar andra poster: skriv INTE en låtsasspec. Flagga posten som **Koncept-kandidat** (formen okänd) eller **Diagnos-kandidat** (orsaken okänd) i granskarblocket, med vad som behöver avgöras. Skriv ändå så mycket av specen som går att skriva — rubrik, problem, det som är känt — så granskaren ser vad som väntar bakom vägvalet.
93
+ **Ett vägval som inte går att avgöra utan kunden** — designfrågor, UX-riktning, okänd felorsak, eller ett val som påverkar andra poster: skriv INTE en låtsasspec. Skriv posten i **kandidatformen** (se `references/specformat.md`, avsnittet Kandidatform): rubriken, direkt under den markörraden `**Koncept-kandidat**` (formen okänd) eller `**Diagnos-kandidat**` (orsaken okänd), på engelska `**Concept candidate**` / `**Diagnosis candidate**`, sedan **Problem** och det som är känt under Ingår inte, Kräver eller Villkor. Ingen Lösning och ingen När det är klart: en kandidat har inget utfall att lova, och med en Lösning är det ingen kandidat längre. Formen är entydig med flit, formkontrollen läser markören och flödet stoppar posten som KONCEPT eller DIAGNOS utan analys eller poäng. Nämn kandidaten även under _Flaggor_ i granskarblocket, med vad som behöver avgöras.
92
94
 
93
95
  ## Output
94
96
 
95
- Skriv varje spec som ett eget block, exakt enligt formatet. Efter alla specar: ett **granskarblock** — internt, följer aldrig med till kund:
97
+ Skriv varje spec som ett eget block, exakt enligt formatet. Efter VARJE spec: ett eget **granskarblock** (`## Till granskaren`) för just den specen, internt, följer aldrig med till kund. I en bunt bär varje block bara det som gäller sin egen spec; det som gäller bunten som helhet (att delarna hör ihop, ordningen dem emellan) står under Flaggor i första specens block. Ett block delat över flera specar fälls av formkontrollen (ADR-0118):
96
98
 
97
99
  ```
98
100
  ---
@@ -101,14 +103,21 @@ Skriv varje spec som ett eget block, exakt enligt formatet. Efter alla specar: e
101
103
  **Antaganden:** [tolkningar av otydligt underlag, en rad var — "tom" om inga]
102
104
  **Vägval jag gjort:** [beslut du fattat på eget bevåg + en rads motivering — märk ut de som rör vad användaren får, de är specbeslut och det är dem granskaren måste titta på]
103
105
  **Öppna utfallsval:** [frågor om vad användaren får som inte gick att avgöra ur underlaget — "inga" om inga. Rena byggbeslut hör inte hit]
104
- **Flaggor:** [Koncept-/Diagnos-kandidat med skäl · misstänkt bunt/beroende till annan post · sådant som ser ut att röra behörighet, betalning, oåterkallelig data eller personuppgifter]
106
+ **Prisavgörande öppet val:** [nej · eller "ja: <valet i en mening, i kundens språk>" när alternativen skiljer sig i vad som måste byggas och du inte kan välja ett utan att gissa kundens avsikt. Inbyggd funktion kontra egenbygge är ALLTID ett ja med båda alternativen namngivna, se nedan. Ett ja stoppar posten före analys tills valet är avgjort; ett val som redan står under "Avgjorda val" i KÄLLOR flaggas aldrig]
107
+ **Flaggor:** [Koncept-/Diagnos-kandidat med skäl (specen själv bär markörraden, det här är granskarens sammanfattning) · misstänkt bunt/beroende till annan post · sådant som ser ut att röra behörighet, betalning, oåterkallelig data eller personuppgifter]
105
108
  **Struket ur underlaget:** [tidsord, belopp, interna anteckningar som inte hör hemma i spec]
106
109
  ```
107
110
 
111
+ **Avgjorda val i KÄLLOR.** Under `## Avgjorda val` i KÄLLOR står val en människa redan tagit. De är fast indata: skriv specen utifrån dem och flagga dem aldrig som öppna eller prisavgörande.
112
+
108
113
  Behörighets-/betalnings-/dataflaggan finns för att poängsättningen väger sådana poster tyngre — granskaren ska inte behöva upptäcka det själv.
109
114
 
110
115
  De två vägvalsraderna är åtskilda för att de kräver olika sak av granskaren: den första är beslut som redan är fattade och bara ska bekräftas, den andra är hål i specen som måste fyllas innan posten går vidare. Ett öppet utfallsval som ligger kvar i den första raden ser ut som ett fattat beslut och passerar granskningen.
111
116
 
117
+ Prisavgörande öppet val är det enda i granskarblocket som stoppar posten. Vanliga öppna utfallsval löses av poängsättarens fyrstegsregel; den här raden är för valet där två alternativ ger två olika priser och bara kunden kan välja.
118
+
119
+ **Egen lösning kontra plattformsfunktion.** Finns i källmanifestet, eller i din egen sökning i repot, en inbyggd funktion i plattformen eller ett redan installerat paket som täcker önskemålet, och du väljer att bygga en egen yta i stället, eller tvärtom väljer bort en fungerande inbyggd yta för en egen, är det ALLTID `Prisavgörande öppet val: ja` med båda alternativen namngivna (inbyggd funktion respektive egenbygge), aldrig ett Vägval jag gjort. Skillnaden i pris mellan de två är som störst just där, och bara kunden kan välja. Ett egenbygge som inte ens nämner den inbyggda ytan ser ut som det enda sättet, och kunden betalar tre gånger priset utan att ha valt det.
120
+
112
121
  ## Exempel i korthet
113
122
 
114
123
  Rått önskemål: _"Som chef vill jag själv kunna radera en skattning så att olämpligt innehåll kan tas bort direkt utan att ringa Haus."_
@@ -34,6 +34,54 @@ Varje spec har exakt de här rubrikerna, i den här ordningen. De tre sista finn
34
34
 
35
35
  **Villkor** _(vid behov)_ — när posten vilar på något vi inte kan verifiera i förväg. "Bygger på att X. Faller det avbryter vi utan kostnad."
36
36
 
37
+ ### Språk
38
+
39
+ Specen skrivs på önskemålets språk, svenska eller engelska. Rubrikerna tas ur
40
+ tabellen nedan på samma språk som brödtexten, aldrig blandat: kunden ser
41
+ rubrikerna, och en engelsk spec under svenska rubriker läses som ett
42
+ klipp-och-klistra-fel. Granskarblocket är internt och alltid på svenska.
43
+ Formkontrollen känner båda kolumnerna och fäller en spec som blandar dem.
44
+
45
+ | Svenska | English |
46
+ | ---------------- | ------------ |
47
+ | Problem | Problem |
48
+ | Lösning | Solution |
49
+ | När det är klart | Done when |
50
+ | Ingår inte | Not included |
51
+ | Utseende | Appearance |
52
+ | Kräver | Requires |
53
+ | Villkor | Conditions |
54
+
55
+ ### Kandidatform
56
+
57
+ När formen eller orsaken inte går att avgöra utan kunden (designfråga,
58
+ UX-riktning, okänd felorsak) skrivs ingen låtsasspec. Posten skrivs i
59
+ kandidatform: rubriken, en markörrad direkt under den, sedan Problem. Lösning
60
+ och När det är klart finns inte, det är hela poängen: en kandidat har inget
61
+ utfall att lova ännu. Ingår inte, Kräver och Villkor får stå med när de är
62
+ kända.
63
+
64
+ Markörraden är en av två, som egen fetstilsrad:
65
+
66
+ | Svenska | English | Utfall |
67
+ | ---------------------- | ------------------------- | --------------------------------------- |
68
+ | `**Koncept-kandidat**` | `**Concept candidate**` | KONCEPT, formen ska tas fram med kunden |
69
+ | `**Diagnos-kandidat**` | `**Diagnosis candidate**` | DIAGNOS, orsaken ska undersökas först |
70
+
71
+ En kandidat går aldrig till analys eller poängsättning. Formkontrollen läser
72
+ markören och flödet stoppar posten som KONCEPT eller DIAGNOS direkt, så att
73
+ den når kunddialogen utan att kosta en bedömning. Skriver du en kandidat med
74
+ en Lösning är det ingen kandidat längre, och formkontrollen fäller den.
75
+
76
+ > **Förhandsgranskning visar ändringen innan den publiceras**
77
+ >
78
+ > **Diagnos-kandidat**
79
+ >
80
+ > **Problem**
81
+ > Förhandsgranskningen svarar "Unable to connect" i skarpt läge medan samma
82
+ > sida fungerar lokalt. Ingen vet ännu om felet sitter i vår konfiguration
83
+ > eller i tjänsten bakom.
84
+
37
85
  ---
38
86
 
39
87
  ## Reglerna
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haus-tech/haus-workflow",
3
- "version": "5.0.1",
3
+ "version": "5.2.0",
4
4
  "description": "Haus AI workflow CLI for Claude Code.",
5
5
  "type": "module",
6
6
  "bin": {