De feedback-loop sluiten vanuit de changelog
8 min lezen
Een klant-feedback-loop is gesloten wanneer de persoon die de feedback gaf te horen krijgt wat ermee is gebeurd. Niet wanneer die wordt geregistreerd. Niet wanneer die wordt geprioriteerd. Zelfs niet wanneer die wordt uitgebracht. Wanneer het haar wordt verteld. De meeste teams doen de eerste drie stappen goed en de laatste helemaal niet, en vragen zich dan af waarom mensen die feedback sturen ermee ophouden.
Dit artikel gaat over die laatste stap, en over een concrete bewering: de changelog is de juiste plek om de loop vanaf te sluiten, omdat het het enige artefact is dat al bestaat op precies het moment waarop de loop gesloten kan worden.
Wat is een klant-feedback-loop?
Een klant-feedback-loop is het pad van een gebruiker die je iets vertelt tot die gebruiker verneemt wat je ermee hebt gedaan. Hij heeft vier stappen: de feedback verzamelen, beslissen wat ermee te doen, het resultaat uitbrengen, en de vrager inlichten. De loop is open tot de vierde stap plaatsvindt. Een team dat feedback verzamelt en fixes uitbrengt maar nooit iemand inlicht heeft een postvak, geen loop.
| Stap | Wat er gebeurt | Waar het meestal breekt |
|---|---|---|
| Verzamelen | Feedback komt binnen: widget, support, sales, interviews | Niets; elk team doet dit |
| Beslissen | Getrieerd, samengevoegd met duplicaten, geaccepteerd of afgewezen | Afwijzingen worden nooit gecommuniceerd |
| Uitbrengen | Iemand bouwt het en het gaat live | De link naar het verzoek raakt kwijt bij de merge |
| Inlichten | De aanvrager verneemt dat het is uitgebracht | Overgeslagen, of alleen gedaan voor de luidruchtigste aanvrager |
De vierde rij is waar dit artikel over gaat. Hij breekt om een structurele reden, niet een culturele: tegen de tijd dat een feature wordt uitgebracht, leeft het verzoek dat het veroorzaakte in een ander systeem dan het uitgebrachte ding, en het is niemands taak om ze te verbinden. De loop begint eerder, bij hoe het verzoek in de eerste plaats wordt gevraagd; klantfeedback vragen behandelt de formulering en het moment.
Waarom blijven feedback-loops open staan?
Feedback-loops blijven open staan omdat het verzoek en de uitgebrachte verandering op verschillende plekken leven en de link ertussen met de hand wordt gemaakt, als dat al gebeurt. Het verzoek staat in een feedbacktool, een supportpostvak of een spreadsheet. De verandering staat in een pull request. De aankondiging staat in een changelog of e-mail. Drie systemen, drie eigenaren, en de link van de derde terug naar de eerste is een persoon die zich maanden later herinnert wie het vroeg.
Er is een tweede reden. De inlicht-stap wordt meestal ingekaderd als een marketingtaak (“de feature aankondigen”) in plaats van een supporttaak (“de persoon antwoorden”). Aankondigingen gaan naar iedereen en bereiken niemand in het bijzonder. De persoon die in maart om de feature vroeg leest de aankondiging in juni, als ze die al leest, als nieuws, niet als antwoord. De loop sluit alleen als het bericht aan haar gericht is.
Waarom de loop sluiten vanuit de changelog?
Omdat de changelog-entry het enige artefact is dat exact op het juiste moment bestaat, exact de juiste woorden bevat, en geschreven wordt door exact de juiste persoon. Hij bestaat wanneer de verandering live is en niet eerder. Hij zegt wat er is veranderd in de taal van de lezer, wat het bericht is dat de aanvrager nodig heeft. En hij wordt geschreven door iemand die net de pull request heeft gelezen, wat het enige moment is waarop de link naar het oorspronkelijke verzoek nog zichtbaar is.
Vergelijk de alternatieven. De loop sluiten vanuit de feedbacktool betekent dat de feedbacktool moet weten wanneer de feature is uitgebracht, wat betekent dat iemand met de hand een status bijwerkt. Hem sluiten vanuit de pull request betekent de klant inlichten bij de merge, voordat de verandering live is, een gebroken belofte met tijdstempel zodra de deploy vertraagt. Hem sluiten vanuit de marketingaankondiging betekent wachten op er een, en de meeste uitgebrachte veranderingen krijgen er nooit een.
De changelog zit in het midden: na de merge, op het moment van uitbrengen, met de formulering klaar.
Hoe sluit de loop, stap voor stap
Dit is het mechanisme dat wij draaien. Het wordt hier beschreven als specificatie in plaats van producttour, omdat elke stap met de hand of met andere tools kan worden gedaan; wat ertoe doet is de volgorde.
- Feedback wordt een issue in de repository die het gaat fixen. Een widget-inzending wordt
geregistreerd als gelabelde GitHub-issue (
feature-requestofbug, een prioriteit, enfrom-widget), met het e-mailadres van de indiener buiten de body van de issue gehouden. De issue leeft naast de code, zodat stap drie hem kan vinden. Een met de hand aangemaakte issue, bijvoorbeeld vanuit een feature-request-template, valt buiten dit pad: stap vijf plaatst er geen reactie op, dus sluit die loop zelf. - De fix verwijst naar de issue. De pull request zegt
Fixes #142, GitHubs eigen sluitwoord. Niets nieuws te leren, en het is dezelfde zin die developers al schrijven. - De changelog-entry wordt opgesteld uit de gemergede pull request en draagt de link. Bij de
merge wordt het concept aangemaakt en
#142wordt uit de PR-body gelezen en aan het concept gehecht. De link wordt gemaakt terwijl hij nog goedkoop is, door een machine, uit data die er al is. - Een mens beoordeelt de entry. Formulering, doelgroep, of het überhaupt gepubliceerd moet worden. Een weggegooid concept sluit niets, wat correct is: een interne refactor die toevallig naar een issue verwees is geen nieuws.
- Bij goedkeuring wordt de aanvrager ingelicht. Een reactie wordt geplaatst op de issue die van haar feedback werd gemaakt, “Shipped —” gevolgd door de titel van de entry en een link naar de gepubliceerde entry, en de widget toont de indiener dezelfde uitgebrachte entry. Eén keer, nooit twee keer, en pas nadat een mens de entry heeft gepubliceerd. Dezelfde entry gaat via feed en widget naar iedereen die niet vroeg.
De volgorde in stap vijf is het hele ontwerp. De aanvrager inlichten bij de merge zou vroeger en makkelijker zijn, en zou fout zijn ongeveer even vaak als deploys vertragen. Een feature flag breekt zelfs deze volgorde, omdat goedgekeurd en gepubliceerd kan gebeuren terwijl de feature nog onzichtbaar is voor het account van de aanvrager; feature flags en featureverzoeken behandelt de extra check die deze stap nodig heeft zodra er een flag bij komt kijken.
Hoe ziet een gesloten loop eruit voor de klant?
Het ziet eruit als een antwoord. De klant stuurde een verzoek via een widget, en op een dag toont de widget het als uitgebracht, met een link naar een entry die het in haar taal beschrijft; op GitHub krijgt de issue hetzelfde nieuws als reactie. Ze abonneerde zich niet op een nieuwsbrief, controleerde geen roadmap, zocht niet in de changelog. Het werd haar verteld.
Dat is de ervaring die het volgende stukje feedback veroorzaakt. Mensen sturen feedback naar producten die antwoorden. De pagina changelog-voorbeelden bevat entries van teams wier gebruikers zichtbaar blijven terugkomen met verzoeken, en de gemeenschappelijke draad is niet de tooling; het is dat de entries lezen als antwoorden.
Hoe meet je een feedback-loop?
Meet het aandeel uitgebrachte veranderingen dat minstens één aanvrager inlichtte, en de tijd van uitbrengen tot inlichten. Twee getallen, allebei makkelijk zodra de link bestaat en onmogelijk daarvoor.
- Sluitingspercentage: van de deze maand gepubliceerde changelog-entries, hoeveel linkten naar minstens één verzoek, en daarvan, hoeveel lichtten de aanvrager in. Als het tweede getal veel lager is dan het eerste, falen de notificaties; als het eerste laag is, worden verzoeken niet vanuit pull requests gerefereerd, en de fix is een zin in de PR-template.
- Tijd van uitbrengen tot inlichten: hoelang tussen de entry die live gaat en het inlichten van de aanvrager. Met het bovenstaande mechanisme zijn het seconden. Met de hand zijn het typisch weken, of nooit, en “nooit” is het getal dat ertoe doet.
Meet de loop niet aan het volume verzamelde feedback. Verzamelen is de makkelijke stap, en een team dat het meet zal het optimaliseren, wat meer open loops oplevert.
Waar past de roadmap?
Een publieke roadmap is een manier om de loop vroeg te sluiten: het vertelt aanvragers dat hun
verzoek is gehoord, voordat het wordt uitgebracht. Het is nuttig, en het vervangt de laatste stap
niet. “Gepland” is een belofte over de toekomst; “Uitgebracht” is een feit over het
heden. Draai de publieke roadmap vanuit dezelfde issues, met een label
per kolom, zodat hetzelfde verzoek van gepland naar uitgebracht beweegt zonder ergens opnieuw te
worden ingevoerd. De stap naar uitgebracht is een labelwijziging (roadmap:shipped) die niemand voor
je maakt wanneer de entry wordt goedgekeurd, dus doe het in dezelfde review.
FAQ
Wat zijn de vier stappen van een klant-feedback-loop? Verzamelen, beslissen, uitbrengen, inlichten. De loop is open tot de vierde stap plaatsvindt. De meeste frameworks voegen analyse- en prioriteringsstappen in het midden toe; het zijn verfijningen van “beslissen”, en geen enkele sluit iets.
Zou je klanten moeten inlichten wanneer een verzoek wordt afgewezen? Ja, en het is het meest verwaarloosde bericht in de loop. Een duidelijk “we gaan dit niet doen, en hier is waarom” beëindigt het wachten. Stilte laat de loop voor altijd open en de klant blijven controleren.
Hoe verschilt de loop sluiten van een feature aankondigen? Een aankondiging gaat naar iedereen. De loop sluiten is een antwoord aan de mensen die vroegen, op het kanaal waarlangs ze vroegen. Doe beide; het zijn verschillende berichten voor verschillende lezers.
Wat als de aanvrager niet op GitHub zit? De meesten zitten er niet, en dat is prima. De widget blijft hun de status tonen van wat ze stuurden, inclusief de uitgebrachte entry en de link ernaar, dus ze hebben niets nodig buiten de pagina waarvandaan ze schreven. De reactie op de issue is voor de mensen die de repository kunnen zien.
Werkt deze loop ook op GitLab of Bitbucket in plaats van GitHub? De widget en de changelog wel; de automatische reactie in stap vijf vandaag nog niet. Een team op GitLab of Bitbucket krijgt nog steeds elke inzending, registreert die nog steeds als issue, en toont de aanvrager nog steeds een status in de widget, maar die specifieke loop terugsluiten naar de issue zelf is voorlopig iets wat je met de hand doet totdat die integratie bestaat.
De technische beweringen in dit artikel zijn niet onafhankelijk gecontroleerd. Klopt er iets niet, laat het ons weten, dan corrigeren we het.