@haus-tech/haus-workflow 4.2.0 → 4.4.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.
@@ -171,7 +171,7 @@ upstream gets pruned automatically by `apply`'s existing orphan-pruning.
171
171
 
172
172
  ### New project (`project:new`)
173
173
 
174
- 1. Open and follow `references/new.md` in this skill's directory. It is a seven-phase AI-driven flow: elicit the request and propose features, gate on user intent, scaffold (registry stacks via `haus new --json --yes` with a `--dry-run` preview; any other stack via a user-confirmed official scaffolder plus manual rails), install context via `haus init`, seed `docs/SPEC.md` + `docs/plans/walking-skeleton.md`, build the walking skeleton with one subagent per feature, and verify (build + lint + tests + smoke boot). Failure `detail` is relayed verbatim and nothing is ever auto-deleted. Never run bare interactive `haus new`.
174
+ 1. Open and follow `references/new.md` in this skill's directory. It is a seven-phase AI-driven flow: elicit the request and propose features, gate on user intent, scaffold (registry stacks via `haus new --json --yes` with a `--dry-run` preview; any other stack via a user-confirmed official scaffolder plus manual rails), install context via `haus init`, seed `docs/SPEC.md` + `docs/plans/walking-skeleton.md`, build the walking skeleton with one subagent per feature (against a structure recorded in `docs/DESIGN.md`), verify (build + lint + tests + smoke boot), then write the project docs by following `references/init.md` from step 3 (deep read, `CLAUDE.md` body + `docs/`, recommend re-check, opt-ins). Repos are only ever created private. Failure `detail` is relayed verbatim and nothing is ever auto-deleted. Never run bare interactive `haus new`.
175
175
 
176
176
  ### Add optional skills (`project:add-skills`)
177
177
 
@@ -204,6 +204,11 @@ choices.
204
204
  2. If the project is already healthy, say so in one line and stop.
205
205
  3. Otherwise, for each item that needs attention, run the exact fix command the
206
206
  doctor named (commonly `haus apply --write` or `haus apply --refill-config`).
207
+ One suggestion is not a shell command: if the doctor suggests running the
208
+ writing-documentation skill (`/docs`) because the project docs were never
209
+ generated, invoke that skill directly (it's installed in this project at
210
+ `.claude/skills/writing-documentation/`) instead of running anything in
211
+ the terminal.
207
212
  4. Re-run `haus doctor` to confirm the verdict is now green.
208
213
  5. Report what you changed in plain language — what was wrong, what you ran, and
209
214
  that it's now resolved.
@@ -23,9 +23,14 @@ Ask about dimensions, never from a domain template:
23
23
  shopping → cart, product pages, login, checkout, search); the user multi-selects
24
24
  and may add their own. Generate this list per request; it is never enumerated here.
25
25
  3. Auth (none / simple / provider) and data (mocked / real DB / external API).
26
- 4. Practicals: project name (lowercase letters, digits, `. _ -`), GitHub org (default:
27
- WeAreHausTech; "personal" = omit `--org`), visibility (private default / public),
28
- create the GitHub repo at all (default yes).
26
+ 4. Practicals: project name (lowercase letters, digits, `. _ -`) and where the code
27
+ lives — exactly three choices, all private, never "public":
28
+ - a private repo in the org (default: WeAreHausTech),
29
+ - a private repo on personal GitHub (omit `--org`),
30
+ - local only, no GitHub repo (`--no-github`).
31
+ NEVER offer or pass `--public`: client projects must not be exposable by one
32
+ mis-click in a menu. A public repo is a deliberate manual act outside this flow
33
+ (the CLI flag exists for that; this skill never uses it).
29
34
 
30
35
  Pick the stack yourself from the answers. Confirm the stack with the user only on
31
36
  genuine ambiguity (e.g. web vs native unclear).
@@ -45,7 +50,7 @@ Check the registry first: `haus new --list --json`.
45
50
  **Stack in the registry (fast path):**
46
51
 
47
52
  1. Preview:
48
- `haus new <stack> <name> --json --yes --dry-run [--org <org>] [--public] [--no-github]`
53
+ `haus new <stack> <name> --json --yes --dry-run [--org <org>] [--no-github]`
49
54
  and show the planned steps in plain language. Phase 2's approval already covers
50
55
  running this for real — no further confirmation needed.
51
56
  2. Execute the same command without `--dry-run`. Parse the JSON:
@@ -68,6 +73,9 @@ Everything from here on runs inside the new project directory — `cd` into it f
68
73
  stay there.
69
74
 
70
75
  - Fast path: the chained `haus init` inside `haus new` already ran — go to seeding.
76
+ (That chained init is the CLI pipeline only: it installs skills and guardrails but
77
+ does not write project docs — those are written in Phase 6, where the deep read
78
+ sees the real code instead of an empty scaffold.)
71
79
  - Manual path:
72
80
  - Read: run `haus init --json --dry-run` and read the envelope yourself.
73
81
  - If it refuses with the zero-signal message — literally zero catalog items matched,
@@ -91,8 +99,17 @@ stay there.
91
99
  loop needs them installed either way.
92
100
  2. Read the new project's `CLAUDE.md` and `.haus-workflow/WORKFLOW.md`; they are
93
101
  authoritative from here on.
94
- 3. Per selected feature: dispatch one subagent per feature with a self-contained
95
- prompt (spec excerpt, file paths, verify command); it builds the feature end-to-end
102
+ 3. Decide the project's file/folder structure BEFORE dispatching any build agent:
103
+ derive it from the chosen stack's own idioms (e.g. Next.js app-router layout,
104
+ NestJS module-per-domain, React Router route-module structure, Expo router
105
+ conventions) plus the installed coding-style rule (organize by feature/domain,
106
+ not by type; many small files). Record the layout as a short tree with one line
107
+ of placement guidance per top-level folder in `docs/DESIGN.md`. Parallel agents
108
+ with no shared conventions each invent their own layout — this step is what
109
+ keeps the result coherent.
110
+ 4. Per selected feature: dispatch one subagent per feature with a self-contained
111
+ prompt (spec excerpt, file paths, the recorded structure conventions from
112
+ `docs/DESIGN.md`, verify command); it builds the feature end-to-end
96
113
  but minimal — pages/routes/models/navigation wired, core logic TDD-tested — and
97
114
  makes one conventional commit on `main`. Not production-complete — a base to
98
115
  iterate on. This session orchestrates only.
@@ -103,12 +120,22 @@ stay there.
103
120
 
104
121
  ## Phase 6 — Verify + hand off
105
122
 
106
- 1. Gate: build passes, lint passes, tests green, dev server boots (smoke check).
123
+ 1. Gate: build passes, lint passes, tests green, dev server boots (smoke check),
124
+ and the layout matches the structure conventions recorded in `docs/DESIGN.md`.
107
125
  Record the results in `docs/plans/walking-skeleton.md`'s verification blocks.
108
- 2. Push to the remote (if a repo was created).
109
- 3. Summarize: what exists, what is mocked, where the spec and plan live, and the
110
- suggested next step — iterate per feature in fresh sessions inside the project
111
- directory.
126
+ 2. Write the project docs: follow `references/init.md` from step 3 to the end —
127
+ deep read, `CLAUDE.md` body + `docs/` files, `.haus-workflow/deep-context.json`,
128
+ the `haus recommend` re-check, the opt-in helpers offer, and the final
129
+ `haus apply --write`. This runs HERE, after the build, on purpose: the chained
130
+ CLI init installs the writing-documentation skill but never executes it, and a
131
+ deep read now sees the real features instead of an empty scaffold — so the docs
132
+ describe reality and `haus recommend` can match what was actually built.
133
+ (init.md steps 1–2 are already covered by Phase 4; do not redo them.)
134
+ Commit the docs output as its own conventional commit.
135
+ 3. Push to the remote (if a repo was created).
136
+ 4. Summarize: what exists, what is mocked, where the spec, plan, and docs live, and
137
+ the suggested next step — iterate per feature in fresh sessions inside the
138
+ project directory.
112
139
 
113
140
  ## Failure rules
114
141
 
@@ -11,6 +11,8 @@ Det är inte artighet — det är hela poängen. Skriver du analysen med klassni
11
11
 
12
12
  Du ställer aldrig frågor tillbaka. Räcker inte underlaget avgör du och redovisar, eller skriver ordagrant att du inte kunnat verifiera.
13
13
 
14
+ Analysen skrivs för `request-classify`, som hämtar ordagranna citat ur den som belägg — och för granskaren som vill kontrollera de citaten när en klassning ser konstig ut. Den är inte skriven för kunden och hamnar inte i ticketens beskrivning.
15
+
14
16
  ## Ingång
15
17
 
16
18
  **Godkänd spec** i Haus specformat. Ett rått önskemål duger inte — då analyserar du din egen tolkning. Saknas specen: avbryt och säg det, skriv den inte själv (`request-write-spec` gör det).
@@ -55,17 +57,19 @@ Varje påstående ska vara belagt i koden eller specen. Kan du inte belägga nå
55
57
 
56
58
  ## Vägval
57
59
 
58
- En verklig gaffel där båda vägarna fungerar. Du väljer och redovisar valet — det är därför ingen människa behövs i det här steget.
60
+ **Du beslutar, du frågar inte.** Ett vägval är en gaffel där båda vägarna fungerar. Du väljer och redovisar valet — det är därför steget klarar sig utan en människa, och det är också vad kunden betalar oss för.
61
+
62
+ Testfrågan: **skulle användaren märka skillnad mellan alternativen?**
59
63
 
60
- Två sorter får du inte ta:
64
+ **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.
61
65
 
62
- **Design, utseende, flöde och UX.** De är kundens. Skriv i stället ut att frågan är öppen, med alternativen. Klassaren skickar posten till Koncept, och det är rätt.
66
+ **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.
63
67
 
64
- **Vägval som ändrar arbetets omfattning väsentligt** — typiskt att lagra på servern i stället för i webbläsaren, eller att bygga nytt i stället för att återanvända. Välj inte tyst. Redovisa båda vägarna med varsin konsekvensbeskrivning och skriv ut att valet är öppet, så att klassaren kan klassa båda och kunden får se dem med varsin prislapp.
68
+ Design, utseende, flöde och UX hör alltid till den andra kategorin.
65
69
 
66
- Du avgör _inte_ om skillnaden når över den gränsen — du känner inte klasserna. Regeln är enkel: rör alternativen olika lager (server mot klient, nytt mot återanvänt, ett flöde mot flera), redovisa båda.
70
+ Ett valt och redovisat vägval är inget öppet vägval. Skriv "vi lägger detta i den delade komponenten eftersom Z", inte "detta kan lösas som delad komponent eller som specialfall".
67
71
 
68
- Ett valt och redovisat vägval är inget öppet vägval. Skriv "vi lagrar X i Y eftersom Z", inte "X kan lagras i Y eller Z".
72
+ **Beslutet är ett kvitto.** Väljer vi tyst bär vi också ansvaret för valet. Redovisningen är därför kvittot: skriv vad som valdes, vad alternativet var, och varför. Det är enda gången någon kan granska omdömet i efterhand — klassningen och priset kommer se rimliga ut oavsett vilket alternativ som togs.
69
73
 
70
74
  ## Antaganden
71
75
 
@@ -86,10 +90,29 @@ Analysen som ett dokument, en sida. Sedan ett kort block till granskaren:
86
90
  ## Till granskaren
87
91
 
88
92
  **Ej verifierat:** [vad du inte kunnat belägga i koden, och varför]
89
- **Öppna vägval:** [de du lämnat öppna med flit — "inga" om inga]
90
93
  **Avvikelse mot specen:** [om koden säger något annat än specen förutsätter]
94
+ **Obesvarade utfallsval:** [ett stycke per val — se nedan]
91
95
  ```
92
96
 
97
+ ### Obesvarade utfallsval
98
+
99
+ Ett utfallsval som specen lämnat öppet skrivs ut med tre saker, och alla tre behövs:
100
+
101
+ 1. **Vilka alternativen är.** Namnge dem, och var i koden vart och ett finns om de
102
+ bygger på något befintligt.
103
+ 2. **Om alternativen skiljer sig i vad som måste byggas.** Skriv rakt ut "båda mönstren
104
+ finns redan, samma arbete oavsett" eller "det ena kräver att X också ändras". Det är
105
+ en observation om koden, inte en bedömning av omfattning — du skriver aldrig att
106
+ något är stort, litet, enkelt eller dyrt.
107
+ 3. **Vilket alternativ analysen är skriven utifrån.** Du måste utgå från något för att
108
+ kunna beskriva systemet. Skriv "beskriven utifrån X", aldrig "vi väljer X" — valet
109
+ är inte ditt.
110
+
111
+ Skälet till punkt 2: den som poängsätter posten har inte repot och kan inte se om
112
+ alternativen kostar olika. Utan din rad måste den anta det värsta och stoppa posten,
113
+ även när båda vägarna är samma arbete. Det är den vanligaste orsaken till att en post
114
+ studsar tillbaka till specen i onödan.
115
+
93
116
  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 klassas.
94
117
 
95
118
  ## Vad du aldrig gör
@@ -41,7 +41,6 @@ Ge inte dig själv repot i den här körningen. Har du det börjar du verifiera
41
41
  "customer": {
42
42
  "class": "",
43
43
  "rationale": "",
44
- "tradeoffs": [],
45
44
  "conditions": [],
46
45
  "dependencies": []
47
46
  },
@@ -67,12 +66,6 @@ Blir utfallet `KONCEPT`, `DIAGNOS` eller `TILLBAKA_TILL_SPEC` sätts `customer.c
67
66
 
68
67
  `INPUT_SAKNAS` och `ESKALERA` är interna. `customer` lämnas tomt; de ska aldrig nå kund.
69
68
 
70
- ### Öppna vägval
71
-
72
- Lämnade `request-assess-impact` ett vägval öppet med flit: klassa **båda** vägarna och lägg dem i `tradeoffs` med varsin klass och en rads konsekvens. Välj inte åt kunden.
73
-
74
- Kalibreringsloggens Vafab-fall är precis det: samma kundbehov, backend- eller webbläsarlagring, en klass i prisskillnad — och valet kom ur intern designdialog snarare än ur kundens behov. Regeln därifrån gäller.
75
-
76
69
  ## Efter körning
77
70
 
78
71
  Granskaren läser svaren fråga för fråga, inte slutklassen. Ett rätt slutresultat med fel belägg är en felkalibrering som råkade landa rätt, och den kommer tillbaka i en post där den inte gör det.
@@ -1,6 +1,6 @@
1
1
  # Klassningsinstruktion (maskinversion)
2
2
 
3
- **v0.5 · Internt.** Körbar instruktion för AI-klassning av ett inkommande önskemål. Principerna finns i klassningsprotokollet, som är överordnat vid konflikt. Det dokumentet är för människor och ingår inte i körningen — hittar du en regelkonflikt eskalerar du enligt regel 6, och granskaren avgör mot protokollet. v0.5: kriterier måste vara oberoende — samma förhållande får inte räknas två gånger, och touchpoint-kriteriet räknar bara lager som inget annat kriterium redan gjort anspråk på. Hålet uppstod i v0.4 när kriterier gick från antingen-eller till att adderas. v0.4: LARGE tillagd och stegen gjorda enhetliga — ett Medium-kriterium är basen, varje ytterligare kriterium och varje bump är ett steg upp, taket är LARGE. Tidigare saknades steget mellan MEDIUM och offert helt, vilket gjorde varje Medium med en bump till offert. v0.3 efter divergenstest (två körningar, samma underlag, olika klass utan eskalering): flerstegsflöde och datamodelländring omdefinierade. v0.2 efter två oberoende testkörningar: konsekvens-B1, bygg-avgränsad B2, undantag för ärvda antaganden och robusthetsinstruktioner, genomförbarhetsvillkor.
3
+ **v0.6 · Internt.** Körbar instruktion för AI-klassning av ett inkommande önskemål. Principerna finns i klassningsprotokollet, som är överordnat vid konflikt. Det dokumentet är för människor och ingår inte i körningen — hittar du en regelkonflikt eskalerar du enligt regel 6, och granskaren avgör mot protokollet. v0.6: B2 omdefinierad. Frågan flyttar från vad planen säger om testning till vad ändringen kräver, och gränsen går mellan verifiering (en människa tittar, kostar minuter) och testning (en människa arbetar sig igenom, kostar timmar). Den gamla lydelsen tillät belägg endast ur byggets verifieringssteg, vilket gjorde att en plan som glömde nämna manuell testning slapp bumpen — kriteriet mätte planens utförlighet i stället för arbetets innehåll. v0.5: kriterier måste vara oberoende — samma förhållande får inte räknas två gånger, och touchpoint-kriteriet räknar bara lager som inget annat kriterium redan gjort anspråk på. Hålet uppstod i v0.4 när kriterier gick från antingen-eller till att adderas. v0.4: LARGE tillagd och stegen gjorda enhetliga — ett Medium-kriterium är basen, varje ytterligare kriterium och varje bump är ett steg upp, taket är LARGE. Tidigare saknades steget mellan MEDIUM och offert helt, vilket gjorde varje Medium med en bump till offert. v0.3 efter divergenstest (två körningar, samma underlag, olika klass utan eskalering): flerstegsflöde och datamodelländring omdefinierade. v0.2 efter två oberoende testkörningar: konsekvens-B1, bygg-avgränsad B2, undantag för ärvda antaganden och robusthetsinstruktioner, genomförbarhetsvillkor.
4
4
 
5
5
  ## Roll och uppgift
6
6
 
@@ -100,7 +100,13 @@ Bumpar mäter konsekvens av fel, aldrig att posten tekniskt vidrör en kategori.
100
100
 
101
101
  **B1 — Konsekvensrisk:** Kan ett fel i just denna post orsaka något av det som listas i KONSEKVENSRISK? Ställ frågan konkret: "vad är det värsta som händer om det här blir fel?" — visas en notis felaktigt är svaret nej; debiteras någon fel eller ser någon annans data är svaret ja. (Att koden anropar eller ligger nära känslig mekanik räcker inte; befintliga mönster som återanvänds räknas aldrig.)
102
102
 
103
- **B2 — Mänskligt testbehov i bygget:** Kräver byggets egen verifiering manuell mänsklig testning i fler än ett scenario, på flera enheter eller i flera miljöer? Belägg får endast hämtas ur byggets verifieringssteg — acceptanstest, kundmoment och verifiering som utförs av någon annan än Haus räknas aldrig (de är leveransvillkor, inte byggkostnad). Automatiska tester och enkel okulär kontroll räknas inte.
103
+ **B2 — Testbehov som inte går att automatisera bort:** Förutsätt att ändringen täcks av automatiska tester, även om de inte finns i dag. Manuell testning ska aldrig göra om det maskinen klarar. Kvarstår något som ändå kräver en människa?
104
+
105
+ _Skilj på verifiering och testning._ **Verifiering** är att en människa tittar och bekräftar att något blev som tänkt: ett nytt menyval, ett fält i ett befintligt formulär, en knapp enligt befintligt mönster, en kolumn i en befintlig tabell. Det kostar minuter och räknas INTE. **Testning** är att en människa måste arbeta sig igenom något: gå ett flöde steg för steg, pröva olika utfall och feltillstånd, använda en fysisk enhet, eller bedöma om upplevelsen håller. Det kostar timmar och räknas.
106
+
107
+ Testning krävs typiskt när ändringen rör: ett nytt eller ändrat flöde som någon måste gå igenom från början till slut · identifiering som inte går att köra automatiskt (BankID, extern inloggningstjänst, betalväxelns egen dialog) · affärskritiska flöden där automatiken finns men inte räcker som enda kvitto före driftsättning (betalning, order, behörighet) · upplevd kvalitet, när bedömningen av hur något känns eller ser ut är poängen med uppdraget — en ny vy, ett omgjort flöde; en justerad färg eller marginal är verifiering · fysiska enheter (AR, kamera, riktiga telefoner, utskrift, skanner) · externa system utan testmiljö, där enda sättet att veta är att köra mot skarpt.
108
+
109
+ Belägg hämtas ur ändringens innehåll: vad som byggs enligt spec och plan. Kundens acceptanstest räknas aldrig — det är ett leveransvillkor, inte en byggkostnad.
104
110
 
105
111
  **B3 — Blast radius:** Ändras något inom DELAD_KOD eller DRIFTMILJÖ så att fler kunder än beställaren, eller SLA-ytan, kan påverkas?
106
112
 
@@ -133,7 +139,7 @@ Svara med exakt denna struktur och inget annat:
133
139
 
134
140
  ## Hårda regler
135
141
 
136
- 1. **Belägg är obligatoriskt.** Varje JA/NEJ ska ha ett ordagrant citat ur spec eller plan. Hittar du inget citat är svaret inte NEJ — det är låg konfidens. Beläggets källa spelar roll: för B2 gäller endast byggets verifieringssteg; citat ur acceptans-/kundmoment är ogiltigt belägg.
142
+ 1. **Belägg är obligatoriskt.** Varje JA/NEJ ska ha ett ordagrant citat ur spec eller plan. Hittar du inget citat är svaret inte NEJ — det är låg konfidens. Beläggets källa spelar roll: för B2 ska citatet visa VAD som byggs (flödet, enheten, den externa tjänsten), inte vad planen råkar säga om testning — en plan som glömmer nämna manuell testning ska inte slippa bumpen. Citat ur acceptans-/kundmoment är ogiltigt belägg.
137
143
  2. **Konfidens < 0.8 på någon fråga → utfall `ESKALERA`.** Klassa aldrig på gissning. En eskalerad post klassas av människa; det är ett korrekt utfall, inte ett misslyckande. Undantag: om frågan inte är utfallsavgörande (svaret ändrar inte slutklassen åt något håll) räcker det att notera den låga konfidensen i frågeraden.
138
144
  3. **Du klassar planen, inte önskemålet.** Önskemålets ton, storleksord ("en liten grej") eller kundens egen bedömning påverkar ingenting.
139
145
  4. **Tid existerar inte i klassningen.** Timmar, estimat och tidsord förekommer varken i din bedömning eller i något outputfält — alla gränser i denna instruktion är strukturella (vad som ändras), aldrig temporala (hur länge det tar).
@@ -0,0 +1,239 @@
1
+ ---
2
+ name: request-score
3
+ description: Sätter poäng på en spec plus påverkansanalys genom att jämföra uppdraget mot en skala av sexton referensuppdrag. Använd alltid när användaren vill "sätt poäng", "poängsätt", "kör poängen", "vad landar det här på", "var på skalan ligger det", eller när en spec har en påverkansanalys och ska prissättas. Används även som grind på en fullständig implementationsplan före första kodraden — "kör guarden", "stämmer poängen fortfarande". Använd den även när poängsättning bara antyds, t.ex. när någon klistrar in en spec med underlag och frågar hur stort det är. Output är JSON med poäng och belägg, aldrig ett pris.
4
+ ---
5
+
6
+ # request-score
7
+
8
+ Du sätter poäng på en post genom att jämföra den mot referensuppdragen i
9
+ `references/poangskala.md`. Läs skalan innan du poängsätter första posten i en session.
10
+
11
+ **Går filen inte att läsa: poängsätt inte.** Säg att `references/poangskala.md` saknas
12
+ och att skillen inte kan köras utan den. Sätt aldrig en poäng på minnet av hur skalan
13
+ brukar se ut. Skalan ändras när nya referensuppdrag läggs till, och en poäng satt på
14
+ en gammal skala ser likadan ut som en satt på rätt skala.
15
+
16
+ **Du sätter aldrig pris.** Poäng blir pris genom en fast processavgift plus poängen
17
+ gånger en konverteringsfaktor, och det räknas någon annanstans. Ligger prislistan i
18
+ sammanhanget: använd den inte och säg till. Vet du vad poängen kostar drar du mot den
19
+ poäng som känns rimlig att ta betalt för, och då mäter du inte längre uppdraget.
20
+
21
+ **Du skriver aldrig underlaget.** Saknas spec eller påverkansanalys, avbryt med
22
+ `INPUT_SAKNAS`. Skriv inte en påverkansanalys själv — då jämför du din egen text mot
23
+ skalan, och belägget blir teater. `request-assess-impact` gör det, helst i en egen
24
+ körning.
25
+
26
+ **Ge inte dig själv repot i den här körningen.** Har du det börjar du verifiera saker
27
+ vid sidan av underlaget, och då poängsätter du inte längre det du fått. Saknas något i
28
+ underlaget är svaret låg konfidens, inte en egen efterforskning.
29
+
30
+ ## Stoppfrågorna först
31
+
32
+ Poäng sätts bara på en post som går att bygga. Tre utfall stoppar poängsättningen:
33
+
34
+ | Utfall | När | Vad som ska hända |
35
+ | --- | --- | --- |
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
+ | `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 |
39
+
40
+ ### Obesvarade utfallsval: förutsättning eller stopp
41
+
42
+ Påverkansanalysens granskarblock listar under _Obesvarade utfallsval_ de val specen
43
+ lämnat öppna, var och en med alternativen, om de skiljer sig i vad som måste byggas,
44
+ och vilket alternativ analysen är skriven utifrån. De ska inte behandlas lika. Ställ en
45
+ fråga per val:
46
+
47
+ **Ändrar valet hur mycket arbete posten kräver?** Analysens rad om huruvida
48
+ alternativen skiljer sig i vad som måste byggas är svaret. Saknas den raden — analysen
49
+ kan vara skriven före den här regeln — behandla valet som ett stopp och skriv i `notes`
50
+ att analysen behöver kompletteras.
51
+
52
+ **Nej** — då är det en **förutsättning**, inte ett stopp. Välj det rimligaste
53
+ alternativet, skriv in det i `assumptions_stated` med vad som valts och varför, och
54
+ poängsätt vidare. Förutsättningarna följer med förslaget till kund tillsammans med
55
+ specen och priset, så kunden godkänner alla tre på en gång. Väljer kunden annorlunda
56
+ är det en ändring som inte rör priset.
57
+
58
+ Typexempel: vilket av två befintliga sätt att visa att något laddar som används, vilken
59
+ av två likvärdiga formuleringar en text får, var i en befintlig vy ett fält placeras.
60
+
61
+ **Ja** — då stoppar posten. Utfallsvalet avgör vad som ska byggas och därmed vad det
62
+ kostar, och att gissa vore att prissätta något kunden inte beställt.
63
+
64
+ Typexempel: om en funktion ska finnas på både mobil och dator eller bara en av dem, om
65
+ befintlig data ska konverteras eller lämnas, om ett flöde ska ha ett steg till.
66
+
67
+ Är du osäker på om valet ändrar arbetsmängden: behandla det som ett stopp och skriv
68
+ ut varför. Ett onödigt stopp kostar några minuter, ett gissat utfallsval kostar en
69
+ felprissatt post.
70
+
71
+ Ett antagande som inte går att undersöka är inget stopp. Det blir ett villkor på posten:
72
+ "bygger på att X; faller X tidigt avbryts posten utan debitering". Osäkerhet löses med
73
+ kunskap eller villkor, aldrig med högre poäng för säkerhets skull.
74
+
75
+ ## Metoden: ringa in, aldrig skatta fritt
76
+
77
+ En siffra som kommer direkt ur en helhetsbedömning går inte att granska och blir olika
78
+ mellan två körningar. Ringa in i stället, i fyra steg. Alla fyra redovisas i utfallet.
79
+
80
+ **Steg 1 — hitta ett golv.** Läs skalan och hitta ett referensuppdrag som posten
81
+ **säkert är större än**. Skriv ut vilket och varför.
82
+
83
+ **Steg 2 — hitta ett tak.** Hitta ett referensuppdrag som posten **säkert är mindre
84
+ än**. Skriv ut vilket och varför.
85
+
86
+ Får du inget golv: posten är mindre än A1 och får A1:s poäng. Skalans nedre ände är
87
+ ändå dominerad av den fasta processavgiften.
88
+
89
+ Får du inget tak: posten är större än skalans högsta referensuppdrag. Sätt utfallet
90
+ till `OVER_SKALAN` och sätt ingen poäng — underlaget för den nivån är för tunt för att
91
+ jämföra mot, och posten ska offereras separat.
92
+
93
+ **Steg 3 — snäva in.** Gå igenom referensuppdragen mellan golv och tak. För varje: är
94
+ posten större eller mindre, och på vilken grund? Fortsätt tills du har två
95
+ angränsande referensuppdrag som posten ligger mellan.
96
+
97
+ **Steg 4 — placera.** Sätt poängen mellan de två. Ligger posten närmare det ena, säg
98
+ vilket och varför. Landar den på samma nivå som ett referensuppdrag, ge den det
99
+ ankarets poäng rakt av.
100
+
101
+ **Avrunda till skalans upplösning.** Under 3 poäng till närmaste 0,25, alltså 0,25,
102
+ 0,5, 0,75, 1, 1,25 och så vidare. Från 3 poäng och uppåt till närmaste hela poäng. En
103
+ finare siffra än så låtsas om en noggrannhet som inte finns: två oberoende bedömare
104
+ hamnar i olika klass i en femtedel av fallen. Avrundningen är mekanisk och sker efter
105
+ placeringen, aldrig genom att du väljer ett rundare tal medan du jämför.
106
+
107
+ ## Vad du jämför på
108
+
109
+ Jämför på vad ändringen **drar med sig**, inte på hur mycket kod som skrivs. Det som
110
+ skiljer referensuppdragen åt, i fallande ordning efter hur mycket de väger:
111
+
112
+ **Om en människa måste verifiera för hand, och i hur många fall.** Det är den tydligaste
113
+ skillnaden genom hela skalan. Ett uppdrag som täcks av automatiska tester ligger lågt.
114
+ Ett som kräver genomgång i flera scenarier, på flera enheter eller i flera miljöer
115
+ ligger högt.
116
+
117
+ **Förutsätt alltid att automatiska tester finns**, även när påverkansanalysen säger att
118
+ repot saknar testsvit. Räkna bara det manuella arbete som återstår när en fungerande
119
+ testsvit gjort sitt: det som kräver en människa av sin natur, alltså kontroll mot en
120
+ extern tjänsts testläge, visuell granskning, eller genomgång på flera enheter eller i
121
+ flera miljöer. Att ett repo saknar tester är Haus egen tekniska skuld, och den ska
122
+ kunden inte betala för. Skriv i så fall en rad om det under `notes`, så att skulden
123
+ syns i stället för att bakas in i priset.
124
+
125
+ **Vad som händer om det blir fel.** Felaktig betalning, felaktig åtkomst till någon
126
+ annans uppgifter, förlorad data eller bruten befintlig funktion väger tungt. Fel text
127
+ eller fel sorteringsordning väger lätt.
128
+
129
+ **Om ändringen rör kod som flera kunder använder.** Då tillkommer migrering per
130
+ installation och en risk som når utanför beställaren. Se A9 och A10.
131
+
132
+ **Om ett externt system berörs**, och om kopplingen är ny eller befintlig.
133
+
134
+ **Om en sekvens som användaren passerar i ordning ändras**, och hur många steg.
135
+
136
+ **Om något ska formges som inte finns i systemet i dag.**
137
+
138
+ Antal filer och antal rader är **inte** jämförelsegrunder. Se noten sist i skalan: två
139
+ referensuppdrag med samma poäng skiljer sig med en tiopotens i filantal.
140
+
141
+ ## Typen
142
+
143
+ Använd typen för att hitta jämförbara referensuppdrag snabbare, ingenting annat. Ett
144
+ uppdrag av en typ som saknas i skalan poängsätts mot de närmaste i storlek, inte mot
145
+ någon påhittad justering. Skriv ut vilken typ du bedömt posten som — den loggas för att
146
+ kunna mäta i efterhand om någon typ hamnar systematiskt fel.
147
+
148
+ ## Grindläget
149
+
150
+ Körs skillen på en fullständig implementationsplan efter kundens godkännande, sätt
151
+ `mode` till `guard`. Samma skala, samma metod.
152
+
153
+ Endast ny strukturell information ur fullplanen får flytta poängen, aldrig en
154
+ omvärdering av samma fakta. Rapportera vilket jämförelsesteg som ändrades och citatet ur
155
+ fullplanen som orsakade det. Grinden är symmetrisk — en lägre poäng rapporteras lika
156
+ tydligt som en högre.
157
+
158
+ Bygger fullplanen ett annat vägval än det som såldes är det en händelse att rapportera
159
+ även när poängen blir densamma.
160
+
161
+ ## Output
162
+
163
+ ```json
164
+ {
165
+ "request_id": "",
166
+ "mode": "pricing | guard",
167
+ "outcome": "POANG | KONCEPT | DIAGNOS | TILLBAKA_TILL_SPEC | OVER_SKALAN | INPUT_SAKNAS",
168
+ "score": null,
169
+ "type": "",
170
+ "bracket": {
171
+ "floor": { "anchor": "", "score": null, "why": "" },
172
+ "ceiling": { "anchor": "", "score": null, "why": "" },
173
+ "between": ["", ""],
174
+ "steps": []
175
+ },
176
+ "drivers": [],
177
+ "confidence": "hog | medel | lag",
178
+ "conditions": [],
179
+ "assumptions_stated": [],
180
+ "dependencies": [],
181
+ "notes": [],
182
+ "customer_rationale": "",
183
+ "guard_diff": []
184
+ }
185
+ ```
186
+
187
+ `score` sätts bara när `outcome` är `POANG`, och alltid på skalans upplösning: steg om
188
+ 0,25 under 3 poäng, hela poäng från 3 och uppåt.
189
+
190
+ `bracket.steps` är jämförelserna från steg 3, en per referensuppdrag du vägde mot, var
191
+ och en med ankarets id, om posten är större eller mindre, och på vilken grund. Det är
192
+ det som gör poängen granskbar. En poäng utan inringning är inte ett giltigt utfall.
193
+
194
+ `drivers` är de två eller tre faktorer som mest avgjorde placeringen, med citat ur
195
+ påverkansanalysen. Citat, inte parafras.
196
+
197
+ `assumptions_stated` är de utfallsval specen lämnat öppna som **inte** ändrar
198
+ arbetsmängden: vad du valt, och varför. De går med förslaget till kund som
199
+ förutsättningar och godkänns tillsammans med specen och priset.
200
+
201
+ `notes` är iakttagelser som inte hör till poängen men som någon bör känna till, till
202
+ exempel att ett repo saknar testsvit.
203
+
204
+ `confidence` sätts till `lag` när posten inte liknar något referensuppdrag, när golv och
205
+ tak ligger långt isär och inget referensuppdrag finns emellan, eller när
206
+ påverkansanalysen anger att något inte kunnat verifieras och det påverkar placeringen.
207
+ Låg konfidens är ett giltigt utfall och ska inte döljas genom att välja en poäng som
208
+ ser rimlig ut.
209
+
210
+ ### Motiveringen till kund
211
+
212
+ `customer_rationale` skrivs i kundens språk och beskriver arbetet som ska göras, inte
213
+ hur skalan räknade. Nämn aldrig poäng, referensuppdrag, ankare eller skalan. Kunden ska
214
+ kunna invända mot omfattningen, inte mot modellen.
215
+
216
+ Den ska vara förenlig med specens _Ingår inte_. Motiverar du poängen med arbete som
217
+ specen uttryckligen undantar har du poängsatt fel post.
218
+
219
+ ## Efter körning
220
+
221
+ Granskaren läser inringningen, inte slutpoängen. En rimlig poäng med fel jämförelser är
222
+ en felkalibrering som råkade landa rätt, och den kommer tillbaka i en post där den inte
223
+ gör det.
224
+
225
+ Korrigeringar går till skalan, alltså till referensuppdragen eller till den här
226
+ instruktionen, och till kalibreringsloggen. Aldrig till priset på den enskilda posten.
227
+
228
+ Visar det sig återkommande att poster av ett visst slag är svåra att placera, är det ett
229
+ tecken på att skalan har ett hål och behöver ett referensuppdrag till. Rapportera det.
230
+
231
+ ## Acceptanstestet — granskarens sak, inte din
232
+
233
+ Skillen verifieras genom att köras mot poster med känt utfall. Det underlaget ligger med
234
+ flit **inte** i den här mappen — en körning som kan läsa facit kan inte längre testas. Du
235
+ ska varken leta efter det eller rapportera det som saknat.
236
+
237
+ För granskaren gäller två mått: att två oberoende körningar av samma post ger samma
238
+ poäng, och att inringningen håller vid granskning. Det första är det som avgör om
239
+ kunderna får samma pris för samma arbete.