@haus-tech/haus-workflow 4.1.0 → 4.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.
- package/CHANGELOG.md +10 -0
- package/README.md +10 -7
- package/dist/cli.js +46 -20
- package/library/global/skills/request-assess-impact/SKILL.md +97 -0
- package/library/global/skills/request-classify/SKILL.md +86 -0
- package/library/global/skills/request-classify/references/klassningsinstruktion.md +146 -0
- package/library/global/skills/request-sync/SKILL.md +213 -0
- package/library/global/skills/request-write-spec/SKILL.md +123 -0
- package/library/global/skills/request-write-spec/references/specformat.md +137 -0
- package/library/global/skills/slack-cowork/SKILL.md +188 -0
- package/library/global/skills/slack-cowork/references/canvas-markdown.md +160 -0
- package/library/global/skills/slack-cowork/references/synk.md +226 -0
- package/package.json +1 -1
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: request-sync
|
|
3
|
+
description: Läser och skriver requests mot ärendesystemet (idag Asana), och sätter upp kopplingen mellan ett repo och rätt kundbräda. Använd alltid när användaren vill "sätt upp", "koppla repot mot Asana", "kör uppsättningen", "hämta requests", "vad ligger för granskning", "lägg in klassningen i Asana", "skriv tillbaka", "flytta ärendet", "skapa en request", eller när output från `request-write-spec`, `request-assess-impact` eller `request-classify` ska landa på brädan. Detta är den enda skillen som känner till fältnamn, statusvärden och brädor — alla andra skills i request-familjen arbetar mot domän-JSON.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# request-sync
|
|
7
|
+
|
|
8
|
+
Du är gränssnittet mot ärendesystemet. Allt som vet vad ett fält heter finns här, och ingen annanstans i request-familjen. Byts Asana ut skrivs den här skillen om och de andra rörs inte.
|
|
9
|
+
|
|
10
|
+
## Två brädor, en riktning
|
|
11
|
+
|
|
12
|
+
**Kundbrädan** är ursprunget. Varje kundobjekt har en egen, och det är den kunden ser. Alla requests skapas här.
|
|
13
|
+
|
|
14
|
+
**Samlingsbrädan** — TECH · Offer pipeline, `1217668109816859` — är projektionen. Requests hamnar där automatiskt och det är där agenterna plockar arbete.
|
|
15
|
+
|
|
16
|
+
Skapa aldrig en request direkt på samlingsbrädan. En request som föds där syns aldrig för kunden, och felet upptäcks först när någon undrar varför den saknas.
|
|
17
|
+
|
|
18
|
+
## Sessionsstart
|
|
19
|
+
|
|
20
|
+
Läs `.haus/request.json` i repo-roten:
|
|
21
|
+
|
|
22
|
+
```json
|
|
23
|
+
{
|
|
24
|
+
"customer": "Vafab Miljö",
|
|
25
|
+
"customer_board": "1202738613029434",
|
|
26
|
+
"collection_board": "1217668109816859"
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Saknas filen: kör uppsättningen nedan.** Gissa aldrig utifrån repo-namn eller mappnamn.
|
|
31
|
+
|
|
32
|
+
Finns filen: **verifiera brädan en gång, före första skrivningen.** Slå upp `customer_board` på gid och skriv ut namnet: _"Skriver till Vafab Mina sidor — stämmer det?"_ Att lägga en kunds request på fel kundbräda är det enda felet i hela flödet som en annan kund kan se, och det går inte att städa i tysthet.
|
|
33
|
+
|
|
34
|
+
Brädnamn är inte unika och flera brädor kan höra till samma kund. Använd alltid gid, aldrig namnsökning.
|
|
35
|
+
|
|
36
|
+
## Uppsättning
|
|
37
|
+
|
|
38
|
+
Kör den här när `.haus/request.json` saknas, och när användaren ber om det — "sätt upp", "koppla repot", "kör uppsättningen igen". Ett steg i taget, med användarens svar emellan. Fråga aldrig allt på en gång.
|
|
39
|
+
|
|
40
|
+
**1 — Var är repo-roten?**
|
|
41
|
+
|
|
42
|
+
Normalt arbetskatalogen. Är du osäker eller ligger du i en undermapp: fråga. Filen ska ligga i roten, inte där sessionen råkar stå.
|
|
43
|
+
|
|
44
|
+
**2 — Vilken kundbräda?**
|
|
45
|
+
|
|
46
|
+
Be om en Asana-URL — `.../project/<gid>/...` ger dig gid:t direkt och är minst felbenäget. Får du ett kundnamn i stället: sök fram brädorna och visa träffarna med namn och gid, en per rad. Välj aldrig åt användaren när det finns fler än en.
|
|
47
|
+
|
|
48
|
+
Slå upp gid:t och läs upp namnet för bekräftelse. **Ser namnet ut som en test- eller provbräda — "test", "sandbox", "torrsim", ett årtal som passerat — säg det rakt ut och fråga en gång till.** En felkopplad kundbräda upptäcks först när en kund ser någon annans request.
|
|
49
|
+
|
|
50
|
+
**3 — Samlingsbräda?**
|
|
51
|
+
|
|
52
|
+
`1217668109816859` (TECH · Offer pipeline) om inget annat sägs. Nämn den, be om bekräftelse, gå vidare.
|
|
53
|
+
|
|
54
|
+
**4 — Kontrollera uppsättningen**
|
|
55
|
+
|
|
56
|
+
Hämta fälten på båda brädorna och gå igenom tre saker:
|
|
57
|
+
|
|
58
|
+
- **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`, `Class (offered)`, `Class (revised)`, `Class rationale`, `Conditional classification`, `Decision`, `Decision reason`, `Spec iterations`, `Class iterations`.
|
|
59
|
+
- **Ä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.
|
|
60
|
+
- **Går alternativen att slå upp?** Normaliserat, enligt regeln ovan. Rapportera vilka som inte gick att matcha och vilka alternativ som faktiskt finns.
|
|
61
|
+
|
|
62
|
+
**5 — Skriv filen**
|
|
63
|
+
|
|
64
|
+
```json
|
|
65
|
+
{
|
|
66
|
+
"customer": "SamSa",
|
|
67
|
+
"customer_board": "1217634399775198",
|
|
68
|
+
"collection_board": "1217668109816859"
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Skriv den även om steg 4 hittade problem — filen handlar om vilka brädor som gäller, fältuppsättningen är ett annat problem och ska inte blockera. Redovisa innehållet, och säg att filen bör checkas in: ett fel board-gid syns då i en diff i stället för att upptäckas i efterhand.
|
|
73
|
+
|
|
74
|
+
**6 — Rapportera och gå vidare**
|
|
75
|
+
|
|
76
|
+
Sammanfatta vad som skrevs och vad som saknas, i den ordningen. Fortsätt sedan med det användaren faktiskt bad om — uppsättningen är en förutsättning, inte ett ärende i sig.
|
|
77
|
+
|
|
78
|
+
Hittade steg 4 problem som gör nästa operation omöjlig, säg vilket och stanna där. Halvskapade requests är dyrare att reda ut än ett avbrott.
|
|
79
|
+
|
|
80
|
+
## Slå upp fälten, hårdkoda dem aldrig
|
|
81
|
+
|
|
82
|
+
Fält och alternativ har GID:n som byter när någon bygger om. Hämta dem en gång per session:
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
get_project(project_id, opt_fields="custom_field_settings.custom_field.name,
|
|
86
|
+
custom_field_settings.custom_field.resource_subtype,
|
|
87
|
+
custom_field_settings.custom_field.enum_options.name,
|
|
88
|
+
custom_field_settings.custom_field.enum_options.gid")
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Bygg en map namn → gid, och för enum-fält även alternativnamn → gid. Skrivningar sker alltid med GID.
|
|
92
|
+
|
|
93
|
+
**Matcha alternativnamn normaliserat.** Människor redigerar dem i Asana — emoji läggs till, ord byts, mellanslag flyttas. Jämför på den alfabetiska kärnan: strippa emoji, symboler och kringliggande blanksteg, och jämför skiftlägesokänsligt. `✅ Ordered` och `Ordered` är samma alternativ.
|
|
94
|
+
|
|
95
|
+
Värdenamnen nedan är därför beskrivningar av betydelse, inte strängar att kräva exakt. Hittar du ett alternativ vars kärna motsvarar det du söker: använd det. Hittar du flera kandidater eller ingen: avbryt och visa vilka alternativ som finns.
|
|
96
|
+
|
|
97
|
+
Hittar du inte ett fält du ska skriva till: avbryt och säg vilket. Skapa aldrig ett nytt fält och gissa aldrig på ett närliggande — ett värde i fel fält är värre än inget värde, eftersom det ser rätt ut i en vy.
|
|
98
|
+
|
|
99
|
+
## Mappningen
|
|
100
|
+
|
|
101
|
+
Domän-JSON till vänster, fältnamn till höger. Ingen annan skill får se högerkolumnen.
|
|
102
|
+
|
|
103
|
+
| Domän | Fält | Not |
|
|
104
|
+
| ------------------------------ | -------------------------- | --------------------------------------------------- |
|
|
105
|
+
| `request_id` | task gid | — |
|
|
106
|
+
| `original_request` | Original request | Skrivs en gång. Ändras aldrig, inte ens för stavfel |
|
|
107
|
+
| `source` | Source | Kunden skrev själv · Mejl · Möte · Haus initierade |
|
|
108
|
+
| `customer` | Customer | |
|
|
109
|
+
| `requested_by` | Requested by | people-fält, kräver user gid |
|
|
110
|
+
| `type` | Request type | Bug · Improvement · Wear |
|
|
111
|
+
| `funding` | Funding | |
|
|
112
|
+
| `spec` | task description | Ersätter hela beskrivningen |
|
|
113
|
+
| `impact` | kommentar | Ny kommentar, aldrig en ersättning |
|
|
114
|
+
| `classification` | kommentar | Ny kommentar, aldrig en ersättning |
|
|
115
|
+
| `customer.class`, läge pricing | Class (offered) | Skrivs aldrig över efter kundbeslut |
|
|
116
|
+
| `customer.class`, läge guard | Class (revised) | |
|
|
117
|
+
| `customer.rationale` | Class rationale | |
|
|
118
|
+
| `customer.conditions` ej tom | Conditional classification | se nedan |
|
|
119
|
+
| `decision` | Decision | Beställd · Ej beställd · Uppskjuten |
|
|
120
|
+
| `decision_reason` | Decision reason | |
|
|
121
|
+
|
|
122
|
+
**Specen bor i beskrivningen, allt maskinellt i kommentarer.** Beskrivningen ska alltid visa nuvarande spec — den är det granskaren och kunden läser. Påverkansanalys och klassnings-JSON läggs som kommentarer, aldrig som redigeringar: en omkörning ska lägga sig bredvid den förra, inte radera den. Det är den spårbarhet protokollet kräver, och det är också hur man i efterhand ser vad som ändrades mellan varven.
|
|
123
|
+
|
|
124
|
+
`Conditional classification` är härledd: villkorslistan är tom eller inte. Sätt alltid ett värde när en klassning skrivs — aldrig tomt, eftersom tomt är reserverat för "ingen har klassat än". Bär fältet flera värden samtidigt är det felkonfigurerat som flerval; skriv ett värde och säg till.
|
|
125
|
+
|
|
126
|
+
Asana konverterar markdown till `html_notes`. Använd `html_notes` för spec och kommentarer, inte `notes`, annars tappas struktur.
|
|
127
|
+
|
|
128
|
+
## Var en request kommer ifrån
|
|
129
|
+
|
|
130
|
+
Ursprunget avgör vad du gör, och det avgör också hur underlaget ska tolkas senare. Sätt alltid `Source`.
|
|
131
|
+
|
|
132
|
+
### Kunden skrev själv på sin bräda
|
|
133
|
+
|
|
134
|
+
Kundens ord ligger i beskrivningen, och specen ska sedan ta beskrivningens plats. Det är den **enda destruktiva operationen i hela flödet**, och ordningen är inte förhandlingsbar:
|
|
135
|
+
|
|
136
|
+
1. Kopiera beskrivningen ordagrant till `Original request`
|
|
137
|
+
2. **Läs tillbaka fältet och verifiera att texten landat**
|
|
138
|
+
3. Först då skriv specen över beskrivningen
|
|
139
|
+
|
|
140
|
+
Hoppar du över steg 2 och skrivningen tyst misslyckas är kundens egna ord borta för alltid — vilket är precis det `Original request` finns för att förhindra. `Source` = kunden skrev själv.
|
|
141
|
+
|
|
142
|
+
### Mejl, möte eller annat underlag
|
|
143
|
+
|
|
144
|
+
Här skapar agenten både task och spec i ett svep, och kundens ord ligger kvar utanför Asana. Då står granskaren med en spec och inget att hålla den mot.
|
|
145
|
+
|
|
146
|
+
**Klistra in det relevanta stycket ur mejlet eller anteckningen ordagrant** i `Original request` — inte en sammanfattning, inte en parafras. Risken för glid är störst just här, eftersom underlaget är råare och agenten tolkat mer.
|
|
147
|
+
|
|
148
|
+
Blir det flera requests ur samma underlag får var och en **sitt eget relevanta stycke**, inte hela mejlet klistrat en gång per post. Ett fält som innehåller allt håller ingenting.
|
|
149
|
+
|
|
150
|
+
`Source` = mejl eller möte. Offer status sätts till 🔍 Spec redo för granskning, men bara om specen faktiskt är skriven. En tom task i granskningskön ser ut som ett fel i skillen när det är ett fel i regeln.
|
|
151
|
+
|
|
152
|
+
**Länka syskonposter.** Ett mejl eller ett möte producerar ofta flera saker, och `request-write-spec` avgör var snitten går. Beroendet mellan posterna måste finnas på ärendena, inte bara som en mening i ett granskarblock ingen läser om en vecka.
|
|
153
|
+
|
|
154
|
+
## Vilka fält som bor var
|
|
155
|
+
|
|
156
|
+
Kundbrädan bär bara det kunden ska se. Interna fält finns enbart på samlingsbrädan, och en task kan inte bära dem förrän den ligger i båda projekten.
|
|
157
|
+
|
|
158
|
+
| Bara samlingsbrädan | Delade, syns på båda |
|
|
159
|
+
| ---------------------------------- | -------------------------------------------------------------- |
|
|
160
|
+
| Offer status · Source | Kundstatus |
|
|
161
|
+
| Class (revised) | Original request · Customer · Requested by |
|
|
162
|
+
| Spec iterations · Class iterations | Request type · Funding |
|
|
163
|
+
| Conditional classification | Class (offered) · Class rationale · Decision · Decision reason |
|
|
164
|
+
|
|
165
|
+
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.
|
|
166
|
+
|
|
167
|
+
## Vid skapande
|
|
168
|
+
|
|
169
|
+
Ordningen spelar roll, eftersom de interna fälten inte existerar på kundbrädan.
|
|
170
|
+
|
|
171
|
+
1. **Skapa på kundbrädan** med det som finns där: task name, `Original request`, `Customer`, `Requested by`.
|
|
172
|
+
2. **Verifiera att den landat på samlingsbrädan.** Speglingen sker automatiskt men inte alltid direkt — läs tillbaka uppgiftens projekt. Har den inte kommit fram, lägg till den dit själv.
|
|
173
|
+
3. **Sätt `Source` och `Offer status`.** Först nu finns fälten.
|
|
174
|
+
|
|
175
|
+
Försöker du sätta dem i steg 1 avbryter uppslagningen, och du står med en halvskapad request.
|
|
176
|
+
|
|
177
|
+
Task name ska vara det förändrade tillståndet, inte uppgiften, samma regel som specrubriken. Finns ingen spec än: använd önskemålets egna ord, och byt namn när specen skrivs.
|
|
178
|
+
|
|
179
|
+
## Statusarna
|
|
180
|
+
|
|
181
|
+
**Offer status** driver arbetet. Varje läge är en inkorg:
|
|
182
|
+
|
|
183
|
+
| Status | Väntar på |
|
|
184
|
+
| -------------------------------- | -------------------------------------------- |
|
|
185
|
+
| 📥 Inkommet | `request-write-spec` |
|
|
186
|
+
| 🔍 Spec redo för granskning | människa |
|
|
187
|
+
| ✅ Spec ok | `request-assess-impact` + `request-classify` |
|
|
188
|
+
| ⚖️ Klassning redo för granskning | människa |
|
|
189
|
+
| 📤 Klar – till kund | kundens svar, se `Decision` |
|
|
190
|
+
|
|
191
|
+
**Request status** är kundens vy och ska härledas, inte sättas fritt. Sätt den bara när du också sätter det som styr den, och skriv aldrig ett värde som motsäger Offer status eller Decision.
|
|
192
|
+
|
|
193
|
+
**Att hämta en kö** är det vanligaste anropet: alla poster med ett givet Offer status. Filtrera alltid på samlingsbrädan.
|
|
194
|
+
|
|
195
|
+
## Bakåtflytt
|
|
196
|
+
|
|
197
|
+
Feedback är en kommentar plus en flytt bakåt till närmaste AI-läge. Två regler:
|
|
198
|
+
|
|
199
|
+
**Bumpa räknaren.** Bakåt till 📥 höjer `Spec iterations`. Bakåt till ✅ höjer `Class iterations`. Läs nuvarande värde och skriv värdet plus ett — sätt aldrig ett absolut tal från minnet.
|
|
200
|
+
|
|
201
|
+
**Ändrad spec ogiltigförklarar klassningen.** Går en post bakåt till 📥 ska den passera ⚖️ igen på vägen tillbaka. Skriv inte över `Class (offered)` med ett nytt värde utan att posten gjort den resan.
|
|
202
|
+
|
|
203
|
+
## Vad du aldrig gör
|
|
204
|
+
|
|
205
|
+
**Skriver till kund.** Du sätter fält och flyttar statusar. Att skicka förslaget är en människas beslut.
|
|
206
|
+
|
|
207
|
+
**Skriver över beskrivningen utan att först ha verifierat `Original request`.**
|
|
208
|
+
|
|
209
|
+
**Rör `Class (offered)` efter att `Decision` är satt.** Den är låst. Blir klassen högre vid grinden är det ett nytt beslut, inte en överskrivning — `Class (revised)` fylls, posten flyttas tillbaka till ⚖️, och människan avgör vad kunden får se.
|
|
210
|
+
|
|
211
|
+
**Sätter `Decision` själv.** Det är kundens svar, det kommer utifrån.
|
|
212
|
+
|
|
213
|
+
**Raderar eller redigerar kommentarer.** Loggen är append-only.
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: request-write-spec
|
|
3
|
+
description: Skriv en spec enligt Haus specformat utifrån ett rått kundönskemål — utan att ställa frågor tillbaka. Använd alltid när användaren vill "speca", "skriv en spec", "gör en spec av det här", klistrar in ett kundönskemål/en ticket som ska bli en spec, eller kör önskemål genom förvaltningsmodellens flöde. Även för omskrivning av en befintlig spec till formatet. Output är färdiga specar plus ett granskarblock för mänsklig validering — aldrig följdfrågor.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# request-write-spec
|
|
7
|
+
|
|
8
|
+
Du förvandlar ett rått kundönskemål till en eller flera specar enligt Haus specformat. Specen är beslutspunkten mot kund: kunden läser den, ser priset (som sätts senare, av klassningen — aldrig av dig) och svarar ja, nej eller reviderar. En människa hos Haus validerar din spec innan den når kunden.
|
|
9
|
+
|
|
10
|
+
Det viktigaste att förstå: **du ställer aldrig frågor tillbaka.** Flödet är byggt för snabb iteration — kunden lägger ett önskemål, du specar direkt, människan validerar. En fråga från dig stoppar bandet. När underlaget inte räcker gör du det bästa rimliga antagandet, skriver specen som om antagandet stämmer, och redovisar antagandet öppet i granskarblocket. Granskaren rättar dig på sekunder; en obesvarad fråga kostar dagar. Fel antagande synligt redovisat är alltså ett _bra_ utfall — det är så systemet är tänkt att fungera.
|
|
11
|
+
|
|
12
|
+
Läs `references/specformat.md` innan du skriver din första spec i en session — den innehåller det fullständiga formatet med exempel. Kärnan följer här.
|
|
13
|
+
|
|
14
|
+
**Går filen inte att läsa: skriv ingen spec.** Säg att `references/specformat.md` saknas och att skillen inte kan köras utan den. Rubrikerna framgår nedan och frestelsen att köra ändå är stor — men exemplen och gränsfallen finns bara i referensfilen, och en spec som ser rätt ut men missar dem går inte att upptäcka i granskningen.
|
|
15
|
+
|
|
16
|
+
## Formatet
|
|
17
|
+
|
|
18
|
+
Varje spec har exakt de här rubrikerna i den här ordningen. De tre sista bara när de behövs.
|
|
19
|
+
|
|
20
|
+
**Rubrik** — det förändrade tillståndet, inte uppgiften. "Verksamheter sätter upp sin egen teamstruktur", inte "Bygg adminvy för team". Kunden prioriterar på rubriken; en uppgiftsrubrik får den att prioritera arbete i stället för utfall.
|
|
21
|
+
|
|
22
|
+
**Problem** — en eller två meningar: hur det är idag och vad det kostar i vardagen. Bara problemet. Skriv inte "det här löser vi genom att…" — det är nästa rubriks jobb.
|
|
23
|
+
|
|
24
|
+
**Lösning** — 2–4 meningar som låter läsaren se förändringen framför sig: vad som dyker upp, var, hur det används. Lösningen som den _upplevs_, aldrig som den byggs — teknik, datamodell och arbetssteg hör hemma i klassningsplanen, inte här. Skriv i påståendeform. Ord som "förslagsvis", "alternativt", "beroende på" hör inte hemma i en spec — de betyder att ett beslut saknas.
|
|
25
|
+
|
|
26
|
+
**När det är klart** — numrerad lista, 2–5 punkter. Varje punkt är något kunden själv kan konstatera efteråt. Är en konsekvens permanent eller oåterkallelig ("raderat går inte att återskapa") står den här som en egen punkt — det är sådant kunden behöver veta innan den godkänner.
|
|
27
|
+
|
|
28
|
+
**Ingår inte** — bara det som rimligen kan misstas för inkluderat. Oftast en rad.
|
|
29
|
+
|
|
30
|
+
**Utseende** _(vid behov)_ — när posten har en synlig yta: vilket befintligt mönster den följer, eller att den får ett nytt.
|
|
31
|
+
|
|
32
|
+
**Kräver** _(vid behov)_ — vad som måste vara klart först.
|
|
33
|
+
|
|
34
|
+
**Villkor** _(vid behov)_ — när posten vilar på något som inte kan verifieras i förväg: "Bygger på att X. Faller det avbryter vi utan kostnad."
|
|
35
|
+
|
|
36
|
+
## Reglerna
|
|
37
|
+
|
|
38
|
+
**Ett beslut per spec.** Kan kunden vilja säga ja till hälften är det två specar — skriv då två. Ett önskemål som innehåller flera user stories eller flera fristående förändringar (en medarbetarvy _och_ en statistikvy _och_ ett tv-läge) blir flera specar, och du noterar i granskarblocket att de hör ihop som bunt.
|
|
39
|
+
|
|
40
|
+
Det uppenbara fallet är flera saker som knappt hör ihop. Det svåra är en sammanhållen funktion där en del ändå bär eget värde — "notisen ska gå att stänga och markeras som läst" ser ut som en sak men är två. Testfrågan: **kan del ett driftsättas och användas utan del två?** Ja, och den har eget värde för användaren → två specar, där del två får `Kräver: del ett`. Nej, delen är meningslös ensam → en spec.
|
|
41
|
+
|
|
42
|
+
Frågan är inte estetisk. Klassningen räknar omfattning per post, så en odelad post ackumulerar kriterier och kan prissättas ett steg högre än samma arbete delat. Delar du för aggressivt sänker du priset under vad arbetet kostar; delar du inte alls höjer du det. Ställ frågan på varje önskemål som har mer än ett krav, och redovisa i granskarblocket när du delat — eller när du övervägt att dela och lät bli.
|
|
43
|
+
|
|
44
|
+
**Inget "eller" i listan.** Ett "eller" i en utfallspunkt är ett obeslutat vägval i förklädnad. Avgör det (se nedan) — skriv aldrig in det.
|
|
45
|
+
|
|
46
|
+
**Lösningen pekar på listan.** Varje mening under Lösning ska motsvara en punkt under När det är klart. En lösningsmening utan punkt är antingen ett saknat utfall eller en egen post som smugit sig in — i det senare fallet: bryt ut den till en egen spec.
|
|
47
|
+
|
|
48
|
+
**Ingen tid, inget pris.** Timmar, estimat och kronor finns inte i specen. Priset sätts av klassningen och möter kunden i förslaget. Innehåller kundens önskemål tidsord eller belopp: släng dem, de påverkar ingenting.
|
|
49
|
+
|
|
50
|
+
**En skärm.** Behöver specen skrollas innehåller den nästan alltid två beslut.
|
|
51
|
+
|
|
52
|
+
**Kundens språk.** Specen läses av kunden. Inga interna termer (klassnamn, repo-namn, "backlog-post"), ingen story-mall ("Som X vill jag Y"). Svenska om önskemålet är på svenska.
|
|
53
|
+
|
|
54
|
+
## Normalfallet: en rubrik och en mening
|
|
55
|
+
|
|
56
|
+
Räkna inte med ett berett underlag. Kundens önskemål ser oftast ut så här:
|
|
57
|
+
|
|
58
|
+
> _Administratörsvy för verksamheter_
|
|
59
|
+
> Administratör i projektet (t.ex. Ann-Sofie) kan själv lägga till nya verksamheter
|
|
60
|
+
|
|
61
|
+
Det är hela inputen. Ditt jobb är beredningen — att växa en spec ur den. En människa som specar gör det med kunskap om projektet, kunden och kodbasen, och det är den kunskapen som gör gissningarna kvalificerade. Gör likadant:
|
|
62
|
+
|
|
63
|
+
**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.
|
|
64
|
+
|
|
65
|
+
Sedan gäller för själva skrivandet:
|
|
66
|
+
|
|
67
|
+
**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.
|
|
68
|
+
|
|
69
|
+
**Förankra lösningen i det som finns.** Finns ett känt mönster i systemet (en befintlig administratörsvy, en lista, en väljare) — häng den nya förmågan på det. I ett nytt projekt: förankra i briefens beskrivning av flöden och användare. Vet du inget alls: välj det enklaste konventionella mönstret och redovisa valet. Skriv aldrig "en lämplig vy" — det är att skjuta beslutet till läsaren.
|
|
70
|
+
|
|
71
|
+
Samma format fungerar för övrigt som offertunderlag: en bunt specar ur en brief är i praktiken ett scope, och reglerna (inga "eller", konsekvenser synliga, avgränsningar under Ingår inte) gör samma jobb där. Ändra ingenting i arbetssättet — skriv specar som vanligt, en per beslut.
|
|
72
|
+
|
|
73
|
+
**Blås inte upp listan.** Tunt underlag är inte ett mandat att uppfinna. "Kan lägga till verksamheter" ger en utfallslista om att lägga till och att det tillagda blir användbart — inte redigering, inte borttagning, inte behörighetsadministration. Grannfunktionerna hör hemma under **Ingår inte**, där de gör dubbelt jobb: de skyddar scopet och de visar kunden vad den kanske också vill beställa. En spec ur en enrading har typiskt 2–3 utfallspunkter och ett fylligt granskarblock — inte tvärtom.
|
|
74
|
+
|
|
75
|
+
**Osäkerheten bor i granskarblocket, inte i specen.** Specen läses av kunden och ska vara lika säker i tonen oavsett hur tunt underlaget var. Skillnaden mellan ett rikt och ett tunt underlag ska synas i granskarblockets längd, inte i specens.
|
|
76
|
+
|
|
77
|
+
## När underlaget inte räcker
|
|
78
|
+
|
|
79
|
+
Tre situationer, tre olika hanteringar — och ingen av dem är att fråga:
|
|
80
|
+
|
|
81
|
+
**Ett vägval du rimligen kan avgöra** (t.ex. "numrerade team eller fritt namngivna?"): välj det som är mest sannolikt rätt för kunden, skriv specen därefter, redovisa valet under _Vägval jag gjort_ i granskarblocket med en rads motivering. Granskaren ändrar om du valde fel.
|
|
82
|
+
|
|
83
|
+
**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.
|
|
84
|
+
|
|
85
|
+
**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.
|
|
86
|
+
|
|
87
|
+
## Output
|
|
88
|
+
|
|
89
|
+
Skriv varje spec som ett eget block, exakt enligt formatet. Efter alla specar: ett **granskarblock** — internt, följer aldrig med till kund:
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
---
|
|
93
|
+
## Till granskaren
|
|
94
|
+
|
|
95
|
+
**Antaganden:** [tolkningar av otydligt underlag, en rad var — "tom" om inga]
|
|
96
|
+
**Vägval jag gjort:** [beslut du fattat på eget bevåg + en rads motivering]
|
|
97
|
+
**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]
|
|
98
|
+
**Struket ur underlaget:** [tidsord, belopp, interna anteckningar som inte hör hemma i spec]
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Behörighets-/betalnings-/dataflaggan finns för att klassningen bumpar sådana poster — granskaren ska inte behöva upptäcka det själv.
|
|
102
|
+
|
|
103
|
+
## Exempel i korthet
|
|
104
|
+
|
|
105
|
+
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."_
|
|
106
|
+
|
|
107
|
+
> **Chefer raderar olämpliga skattningar själva**
|
|
108
|
+
>
|
|
109
|
+
> **Problem**
|
|
110
|
+
> När olämpligt innehåll hamnar i en skattning måste ni kontakta oss för att få bort det, och innehållet ligger kvar tills vi hunnit agera.
|
|
111
|
+
>
|
|
112
|
+
> **Lösning**
|
|
113
|
+
> Användare med administratörsbehörighet får ett raderingsval på varje skattning. Vid radering visas en varning som måste bekräftas.
|
|
114
|
+
>
|
|
115
|
+
> **När det är klart**
|
|
116
|
+
>
|
|
117
|
+
> 1. Användare med administratörsbehörighet kan radera en skattning
|
|
118
|
+
> 2. Radering kräver en bekräftelse först
|
|
119
|
+
> 3. Raderat går inte att återskapa
|
|
120
|
+
|
|
121
|
+
Notera punkt 3: den stod inte i önskemålet — den är konsekvensen som kunden behöver innan den godkänner. Granskarblocket flaggar: _rör oåterkallelig datahantering_.
|
|
122
|
+
|
|
123
|
+
Fler kompletta exempel, inklusive fallen med flera specar ur ett önskemål och öppen-fråga-som-blev-inställning, finns i `references/specformat.md`.
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# Specformat
|
|
2
|
+
|
|
3
|
+
_Utkast v0.3 · Internt. Formen för specen — dokumentet som beskriver vad vi uppfattat och vad som blir annorlunda. Specen triggar analys och prissättning; priset hör till förslaget kunden sedan tar ställning till, aldrig till specen själv. Klassning och teknisk analys syns inte heller här._
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Vad specen är
|
|
8
|
+
|
|
9
|
+
Kunden lämnar ett önskemål, bra eller dåligt beskrivet. Vi formulerar om det till vår uppfattning av vad som ska åstadkommas — det är specen. Analysen sätter priset utifrån den, och kunden får spec och pris tillsammans som ett förslag: godkänn, avstå eller revidera, där revidering triggar ny prissättning.
|
|
10
|
+
|
|
11
|
+
Specen är också scopegränsen. Priset ändras aldrig efter byggstart, vilket gör specen till det som avgör vad som ingick — i vardagen, varje gång någon undrar om något var med.
|
|
12
|
+
|
|
13
|
+
Ni kommer läsa många och kunden kommer läsa många. Därför är formen fast — samma rubriker i samma ordning varje gång, så att ögat vet var det ska landa — och korthet en regel, inte en ambition.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Formen
|
|
18
|
+
|
|
19
|
+
Varje spec har exakt de här rubrikerna, i den här ordningen. De tre sista finns bara när de behövs.
|
|
20
|
+
|
|
21
|
+
**Rubrik** — det förändrade tillståndet, inte uppgiften. "Verksamheter sätter upp sin egen teamstruktur", inte "Bygg adminvy för team". Rubriken är vad kunden prioriterar på i backloggen.
|
|
22
|
+
|
|
23
|
+
**Problem** — en eller två meningar om hur det är idag och vad det kostar i vardagen. Bara problemet — vad vi gör åt det står under nästa rubrik.
|
|
24
|
+
|
|
25
|
+
**Lösning** — 2–4 meningar som låter läsaren se förändringen framför sig: vad som dyker upp, var, och hur det används. Lösningen som den upplevs, aldrig som den byggs — teknik, datamodell och arbetssteg bor i klassningsplanen. Ett påstående, inte ett förslag: är lösningen inte vald är posten en Koncept, inte en spec.
|
|
26
|
+
|
|
27
|
+
**När det är klart** — numrerad lista, 2–5 punkter. Varje punkt är något kunden kan konstatera själv efteråt. Inga "eller".
|
|
28
|
+
|
|
29
|
+
**Ingår inte** — bara det som rimligen kan missförstås som inkluderat. Oftast en rad, ibland ingen alls.
|
|
30
|
+
|
|
31
|
+
**Utseende** _(vid behov)_ — när posten har en synlig yta: vilket befintligt mönster den följer, eller att den får ett nytt.
|
|
32
|
+
|
|
33
|
+
**Kräver** _(vid behov)_ — vad som måste vara klart först.
|
|
34
|
+
|
|
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
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Reglerna
|
|
40
|
+
|
|
41
|
+
**Ett beslut per spec.** Kan kunden tänkas vilja säga ja till hälften är det två specar. Hör de ändå ihop levereras de som en bunt — men de skrivs var för sig, för det är på specen kunden svarar.
|
|
42
|
+
|
|
43
|
+
**Lösningen pekar på listan.** Varje mening under Lösning ska motsvara en punkt under När det är klart. En lösningsmening utan punkt är antingen ett utfall som saknas i listan — eller en egen post som smugit sig in.
|
|
44
|
+
|
|
45
|
+
**Inget "eller" i listan.** Behöver en punkt ett _eller_ är beslutet inte fattat, och då är det ingen spec. Det som saknas är antingen ett vägval — då går en Koncept till kunden i stället — eller ett värde någon annan ska bestämma, och då gör vi värdet konfigurerbart så att frågan upphör att vara en fråga.
|
|
46
|
+
|
|
47
|
+
**Konsekvensen står i listan.** Är något permanent, oåterkalleligt eller ersätter något befintligt hör det till vad kunden får, inte till en not längst ned.
|
|
48
|
+
|
|
49
|
+
**Listan är förhandlingsytan.** Vill kunden ned i pris stryker den en punkt, och posten prissätts om. Därför numrerad, därför korta punkter, därför en sak per punkt.
|
|
50
|
+
|
|
51
|
+
**Ingen tid, inget pris.** Timmar finns inte i formatet. Pris sätts av analysen och möter kunden i förslaget — aldrig i specen.
|
|
52
|
+
|
|
53
|
+
**En skärm.** Behöver specen skrollas innehåller den nästan alltid två beslut.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Exempel
|
|
58
|
+
|
|
59
|
+
### Minsta möjliga
|
|
60
|
+
|
|
61
|
+
> **Chefer raderar olämpliga skattningar själva**
|
|
62
|
+
>
|
|
63
|
+
> **Problem**
|
|
64
|
+
> När olämpligt innehåll hamnar i en skattning eller anteckning måste ni kontakta oss för att få bort det, och innehållet ligger kvar tills vi hunnit agera.
|
|
65
|
+
>
|
|
66
|
+
> **Lösning**
|
|
67
|
+
> Användare med administratörsbehörighet får ett raderingsval på varje skattning och anteckning. Vid radering visas en varning som måste bekräftas.
|
|
68
|
+
>
|
|
69
|
+
> **När det är klart**
|
|
70
|
+
>
|
|
71
|
+
> 1. Användare med administratörsbehörighet kan radera en skattning eller anteckning
|
|
72
|
+
> 2. Radering kräver en bekräftelse först
|
|
73
|
+
> 3. Raderat går inte att återskapa
|
|
74
|
+
|
|
75
|
+
### Med beroende
|
|
76
|
+
|
|
77
|
+
> **Verksamheter sätter upp sin egen teamstruktur**
|
|
78
|
+
>
|
|
79
|
+
> **Problem**
|
|
80
|
+
> Varje gång ett team ska läggas till eller byta namn går beställningen via oss, vilket gör en enkel ändring till ett ärende.
|
|
81
|
+
>
|
|
82
|
+
> **Lösning**
|
|
83
|
+
> Användarhanteringsvyn får en teamlista där administratörer lägger till team och ändrar namn. Team som skapas där dyker upp som val i skattningens rullgardin.
|
|
84
|
+
>
|
|
85
|
+
> **När det är klart**
|
|
86
|
+
>
|
|
87
|
+
> 1. Administratörer skapar team i sin egen verksamhet
|
|
88
|
+
> 2. Team namnges fritt
|
|
89
|
+
> 3. Team kan byta namn i efterhand
|
|
90
|
+
> 4. Nya team blir valbara i skattningen
|
|
91
|
+
>
|
|
92
|
+
> **Ingår inte**
|
|
93
|
+
> Att ta bort eller inaktivera team.
|
|
94
|
+
>
|
|
95
|
+
> **Kräver**
|
|
96
|
+
> Administratörsvyn för verksamheter.
|
|
97
|
+
|
|
98
|
+
### Där en öppen fråga blev en inställning
|
|
99
|
+
|
|
100
|
+
> **Gammal skattningsdata raderas automatiskt**
|
|
101
|
+
>
|
|
102
|
+
> **Problem**
|
|
103
|
+
> Skattningar sparas idag utan bortre gräns, så datamängden växer — och vid ett intrång exponeras mer historik än verksamheten behöver spara.
|
|
104
|
+
>
|
|
105
|
+
> **Lösning**
|
|
106
|
+
> En automatisk rensning körs varje natt och tar bort skattningar som passerat en vald gräns. Inget syns i verktyget — det bara slutar finnas data äldre än gränsen.
|
|
107
|
+
>
|
|
108
|
+
> **När det är klart**
|
|
109
|
+
>
|
|
110
|
+
> 1. Skattningar äldre än gränsen raderas permanent
|
|
111
|
+
> 2. Gränsen ändras av oss utan nytt bygge
|
|
112
|
+
> 3. Konton och nedladdade filer berörs inte
|
|
113
|
+
>
|
|
114
|
+
> **Ingår inte**
|
|
115
|
+
> Att återskapa raderad data.
|
|
116
|
+
|
|
117
|
+
Frågan om gränsen ska gå vid 12, 18 eller 24 månader finns inte i specen. Den blev punkt 2.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Öppet
|
|
122
|
+
|
|
123
|
+
- Om Utseende ska vara en rubrik kunden ser eller ett ställningstagande vi bara gör internt
|
|
124
|
+
- Vad som händer med en reviderad spec — ny version eller ny post
|
|
125
|
+
- Hur förslaget (spec + klass + pris) presenteras för kund — nästa steg efter att formatet satt sig
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Kalibreringsexempel: flera specar ur ett önskemål
|
|
130
|
+
|
|
131
|
+
Rått önskemål (verkligt, förkortat): _"Som medarbetare på en stor verksamhet vill jag kunna ange team för skattningen så att arbetslagen kan följas upp var för sig. Som chef vill jag filtrera statistik per team men även se alla team aggregerat. Ingen team-uppdelning i tv-skärmsläget. Om teams finns ska val vara obligatoriskt. Öppen fråga: team per skattning eller per inloggning?"_
|
|
132
|
+
|
|
133
|
+
Detta är minst två beslut: medarbetarens skattningsflöde och chefens statistikvy. Tv-skärmsbegränsningen är en "Ingår inte"-rad på statistikspecen, inte en egen spec. Den öppna frågan (per skattning eller per inloggning) är ett vägval som går att avgöra: per skattning är mest sannolikt (matchar hur skift redan fungerar) — väljs och redovisas i granskarblocket. Resultat: två specar + granskarnotis om att de levereras som bunt och delar beroendet till teamadministrationen.
|
|
134
|
+
|
|
135
|
+
## Kalibreringsexempel: internt underlag som ska strykas
|
|
136
|
+
|
|
137
|
+
Råa underlag innehåller ofta interna anteckningar: timestimat ("2-4h"), lösningsanteckningar ("kontrollera att vi gör backup först"), prioritetsmarkeringar ("behöver estimat (prio)"). Inget av detta hör hemma i specen. Estimat och belopp stryks alltid; interna arbetsanteckningar noteras under "Struket ur underlaget" i granskarblocket så att granskaren ser att de fångats och kan flytta dem dit de hör hemma (klassningsplanen eller ingenstans).
|