Agentvy
Beslutsregistret
ADR:erna: vad som är bestämt, varför, och vad som ännu inte är avgjort.
page manifest · /dev/beslutid: beslut
path: /dev/beslut
titel: Beslutsregistret
summering: ADR:erna: vad som är bestämt, varför, och vad som ännu inte är avgjort.
nyckelord: adr, beslut, arkitektur, register
## Antagna beslut
Ett arkitekturbeslut skrivs som en kort ADR i docs/beslut/ i samma commit som ändringen. Ändras ett beslut ersätts ADR:en, den skrivs inte om.
ADR | Beslut | Status | Innebörd
ADR-001 | App Router istället för Pages Router | Antagen | Kommunens starter kör Pages Router; ett nybygge väljer App Router. Server components passar modulkompositionen och det är Next:s huvudspår framåt.
ADR-002 | Egen designgrund istället för @sk-web-gui | Ersatt | Formspråket i V3 skulle inte tvingas in i ett bibliotek som bär sin egen design. Ersatt av ADR-008, som behåller slutsatsen men byter grund.
ADR-003 | "Sidor" är en egen sidtyp | Antagen | Redaktionellt innehåll beskrivs av ett tunnare PageManifest vid sidan av ModuleManifest. Två varianter av samma sidtyp: sektionsingång och artikel.
ADR-004 | routes + fokusläge i ModuleManifest | Antagen | En modul kan äga en helskärmsvy. mode: "focus" ger topprad med Avbryt och inget annat krom.
ADR-005 | Flödesmotorns kontrakt | Skrivs | Skrivs i M4, när motorn lyfts ur felanmalan till packages/flow-engine.
ADR-006 | Rollen i cookie; moduler hämtar egen data | Antagen | Demoanvändaren bor i en cookie och läses på servern. Modulerna är server components som hämtar sin egen data i stället för att få den i props.
ADR-007 | Aggregerande moduler | Antagen | Modulen agera äger ingen egen data utan renderar andras actions. Registret läses via provideRegistry.
ADR-008 | shadcn/ui som komponentgrund | Antagen | Komponenterna kopieras in i repot och all färg går genom våra egna CSS-variabler. Radix bär tillgängligheten; primitivernas API är oförändrat.
ADR-009 | Designsystemet som data | Antagen | Systemet skrivs som typad data och renderas som sida, JSON och plattext ur samma källa. Stabila id, uttömmande varianter, felindex i formen fel → rätt → varför.
ADR-010 | Devportalen som ingång för människa och agent | Antagen | Allt en byggare behöver samlas under /dev, i två vyer ur samma data. Designsystemet blir en del av portalen och nås på /dev/ui.
ADR-011 | Dokumentation som leveransvillkor | Antagen | Varje del har ett dok i portalen enligt ett dokumentationskontrakt. Klar betyder körbar, granskad och dokumenterad; täckningen räknas fram på /dev/docs.
ADR-012 | Åtkomstkod som demospärr | Antagen | ACCESS_CODE låser demon i middleware. Projektsidan, prototypens ingång, visionssidan och devportalen är öppna, så att dokumentationen går att läsa och hämta av verktyg. Uttryckligen inte autentisering: koden delas av alla och säger ingenting om vem användaren är.
ADR-014 | Portalens påståenden verifieras | Antagen | Det portalen påstår om koden kontrolleras av yarn test och yarn lint: drifttester, uppräkningsbara fält där det stod prosa, lintregel för R4 och namngivna antimönster. Går ett påstående inte att kontrollera ska räckvidden stå utskriven.
ADR-013 | Signerad fältförankring mellan turer | Antagen | Fältens tidigare värden skickas tillbaka så att assistenten inte formulerar om dem, men bara med serverns egen HMAC. Utan signaturen vore de en inmatningsväg förbi samtalet.
ADR-015 | Dokumentflöden definieras som data i modulen | Antagen | Ett dokument med typade avsnitt passar inte i FlowDefinition, som beskriver platta fält. Definitionen bor i modulen med samma bärande idéer, och ADR-005 skrivs i M4 mot två former i stället för en. Utan fältförankring: varje avsnitt går att skriva i direkt, så klientens värden är inte en väg förbi samtalet utan själva inmatningen. ADR-013 gäller flöden där modellens extraktion är enda källan.
ADR-016 | PageManifest med källoberoende innehåll | Antagen | PageManifest skrivs i module-sdk med parent (hierarkin) och content (statiskt eller en källa). Innehållet är typade block, aldrig HTML. Första källan är Sitevisions headless-API på sundsvall.se, med timeout, cache och inspelad reserv; adaptern bor i modulen webbsidor tills en andra konsument finns.
ADR-017 | En Sitevision-webbplats inramad i skalet | Antagen | Simulerar en väg tillbaka till startsidan från Sitevision: webbplatsens meny som rad överst, sidorna i en sandlådad ram med skalet runt. PageLayout får "embed"; skalet äger listan webbplatser och läser källans ramskydd i förväg. En sida visas via REST som jämförelse. Tillägg: exemplen samlas i sektionen Sitevision, och menyraden visas bara inne på webbplatsen.
ADR-018 | Användaren ordnar korten på startsidan | Antagen | Läget "Anpassa startsidan" med dragning (@dnd-kit) och knappar som alternativ, tillgängligt enligt WCAG 2.2: fokus stannar, flyttar annonseras med plats, reducerad rörelse respekteras, Ångra finns. Ordningen sparas per roll i en kaka som servern läser. Inga kort låses till en spalt: varje kort ligger i en @container och anpassar sig efter sin bredd (R11). Widget får label.
ADR-019 | Modulvyer med skalets krom och vägparametrar | Antagen | mode "standard" från ADR-004 byggs: modulvyer under /verktyg/ med sidopanel och menyrad. path får parametrar (/verktyg/personal/:id) som vyn får som params. Fokusflöden ligger kvar under /flode/.
ADR-020 | Notiserna kommer från modulerna och leder till funktioner | Antagen | ModuleManifest.notifications och notificationsFor, som actions i ADR-007. Varje notis har href till funktionen. Klockan är en panel i skalet; läst sparas per roll i en kaka. Notiser räknas fram ur datat, t.ex. ett utvecklingssamtal som väntar på chefens godkännande.
ADR-021 | Fokusytan under AI-fältet på startsidan | Antagen | slots.fokus lämnar en FokusItem som data; skalet visar den nyaste som inte stängts under AI-fältet, formad som en nyhet med bild, tills användaren stänger den. Stängt sparas per roll i en kaka. Demoknapp i användarmenyn.
ADR-022 | Ingångens egna kort och hopfällbara block – IT-support som första sida | Antagen | IT-support byggs som första sida enligt ADR-003. Prövningen ger PageManifest.slots (modulens egna kort på en ingång), PageContent.cards (fler redaktionella kort), blocket details (hopfällbar fråga med valfritt chip) och QuickLink.cta. Felanmälans nav-post flyttar till sidans snabbväg.
ADR-023 | Min AI – en personlig assistent med Eneos sessionskontrakt | Antagen | Min AI är en modul med modulvy, navpost och kort på startsidan. Kontraktet är Eneos ({ question, session_id }), så att motorn kan bytas mot Eneo i route handlern. Samtalen och historiken bor på servern och nås bara av ägaren. Svaret strömmas som text och renderas som typade block, aldrig HTML.
ADR-024 | Verktyg, skills och MCP-tjänster i Min AI | Antagen | Min AI får webbsök, skapa bild (SVG), skapa dokument (.docx) och skapa graf, plus MCP-tjänster via Anthropics connector. Användaren slår på och av var och en i skrivfältet; valen sparas på servern, som ensam avgör vilka verktyg modellen får. Egna verktyg har strict-schema mot modellen och zod-validering på servern. Nya diagramtokens --color-graf-1…4.
ADR-025 | Modulvyer över hela arbetsytan, och genvägar bredvid hälsningen | Antagen | mode: "full" ger en modulvy under /verktyg/ med sidopanelen kvar men hela arbetsytan i skärmens höjd – ingen marginal, sidfot eller AI-knapp. slots.genvag ger knappar bredvid hälsningen på startsidan, AI-tonade med ai: true. Min AI använder båda: knappen ersätter kortet, och samtalet tar ytan som i de stora chattjänsterna, med plats för ett dokument till höger.
ADR-026 | AI tonas i blått, inte grönt – grönt är bara status | Antagen | Grönt är status – klart, godkänt, positivt – och betyder aldrig AI. AI-tokens behåller namnen men byter till blå toner, ljusare än identitetsblått (--color-ai #1f64b8). Signalen för AI är märkningen ✦/AiChip, inte färgen. Ersätter regeln att grönt är reserverat för AI.
ADR-027 | Målgruppsingång – Verktygslådan under Digitalisering, IT och AI | Antagen | En målgruppsingång är en sektion med en ingång – inget nytt i kontraktet. Sektionen Digitalisering, IT och AI får ingången Verktygslådan, porterad från den fristående verktygslådan, med katalog, verksamheter, omvärld och kontakt som egna kort och en artikel per verktyg. Det databasburna (digitala arvet, PIOS, nyttoportföljen) stannar i verktygslådan.
ADR-028 | Workshoprösten – röstkoder utanför spärren, prickar i en fil | Antagen | Prioriteringen efter workshopen görs med prickröstning på /rosta. En röstkod per deltagare, framräknad ur adminkoden med HMAC och aldrig sparad, ger tre prickar. Sidan och API:t ligger utanför demospärren: röstkoden är nyckeln, och lapparna visas i publik form. Prickarna sparas i en JSON-fil på en volym – ingen databas för en workshop. Röstkoden är en biljett, inte en identitet; ingenting byggs ovanpå åtkomstkakan.
ADR-029 | Projektets sida på roten, prototypen på /portal | Antagen | Roten blir projektets sida: vad projektet är, var det står, vad som kommer och allt material samlat, med "Testa prototypen" som huvudärende. Den tidigare introsidan med rollvalet flyttar till /portal, och Logga ut leder dit. Båda är öppna och skrivs publikt; projektboken, tidslinjen, samtalen och workshopen ligger kvar bakom spärren och får bara en rubrik på roten.
ADR-030 | Kompetens är ett register, inte ett LMS | Antagen | Kommunen köper eller bygger inget nytt LMS. Lärplattformen (Moodle) förblir kursmotorn; det som saknas – vad en person har, vad rollen kräver och när det går ut – blir ett eget register bakom WSO2 med kontraktet kompetens@1, matat från Moodle, ID06, Skolverket och chefens intyg. Startsidan visar det som modulen kompetens, som ersätter utveckling. Planen föds ur utvecklingssamtalet; servern prövar varje aktivitet innan något sparas.
ADR-031 | Projektboken ordnas efter typ, inte efter tillfälle | Antagen | Projektbokens meny har fasta flikar – Läget, Tidslinjen, Spåren, Beslut och frågor, Material – som inte blir fler när projektet växer. Allt är typade poster med en fast adress. Varje möte och workshop får en sida under /projekt/handelser/<datum>-<namn>, och tidslinjen är ingången till dem, senast först med filter på slag och spår. Läget skrivs över; historiken läggs till. Toppraden bär kommunens logotyp enligt kommunikationsguidens mall.
ADR-032 | Projektet är roten, med statusrapporter och funktionerna | Antagen | Projektbokens innehåll flyttar från /projekt till roten och den gamla projektsidan slås ihop med Läget. Prototypen står överst men lågt. En topprad med fasta flikar gäller alla projektets sidor. Statusrapporter på /status skrivs i ett formulär eller via /api/status med skrivnyckeln STATUS_SKRIVNYCKEL, och servern prövar varje fält. Funktionerna samlas på /funktioner i tre lager. Allt är öppet utom mötenas anteckningar och ritningen; gamla adresser leds permanent vidare.
ADR-033 | Projektets meny är en klassisk huvudmeny enligt WCAG 2.2 AA | Antagen | Flikraden ersätts av en klassisk huvudmeny efter header A: Start, Status, Tidslinje, Beslut och Funktioner, och grupperna Dokument och Teknik som fälls ut, i en rad dockad mot toppradens underkant under avsändaren. Prototypen länkas inte från projektets yta tills vidare; den nås på /portal. Grå text, blått och ett streck för sidan man är på. Under md en Meny-knapp med samma lista, en post per rad; toppraden klistrar bara från lg. W3C:s disclosure-mönster med aria-expanded och aria-current, Escape stänger. Hopplänk till <main id="innehall"> på varje sida med toppraden. Menyn är data i projektyta/meny.ts.
ADR-034 | Projektstödet svarar bara utifrån projektets öppna sidor | Antagen | Fråga om projektet är ett stöd för att förstå projektet, inte en chattassistent: en frågeruta på startsidan och en knapp på varje öppen undersida. Underlaget är de öppna sidorna som en besökare ser dem – servern läser sina egna sidor utan kaka – och ett test fäller bygget om en sida i underlaget är låst. Varje sida är ett dokument med källhänvisningar, så att svaret visar var det står. Servern äger samtalet; /api/fraga är öppen med egna takgränser. Claude Opus 5.5 som standard, utbytbar med PROJEKTSTOD_MODELL.
ADR-035 | Notiser till teamschatten via ett flöde i Power Automate, avstängda tills de slås på | Antagen | Nya händelser i tidslinjen blir kort i teamets gruppchatt. Ett flöde i Power Automate tar emot kortet och publicerar det som Flödesrobot; Teams gamla Incoming Webhooks är avvecklade. Servern skickar när en ny version startar, så att sidan finns, och minns vad som skickats i datavolymen. TEAMS_NOTISER är av som standard; första gången och i läget logg markeras allt utan att skickas. Varje inlägg i tidslinjen godkänns av Jari Koponen innan det läggs till, och varje godkänt inlägg skickas oavsett slag, högst fem kort per start.
ADR-036 | Att göra-listan redigeras på sidan och bor i en SQLite-fil | Antagen | Uppgifterna på /att-gora läggs till, ändras och byter läge på sidan av den som loggat in med samma skrivnyckel som statusrapporterna; åtkomstkoden räcker inte. De bor i en SQLite-fil med Nodes inbyggda node:sqlite i datavolymen, ATT_GORA_FIL. uppgifter.ts är startdata: det som saknas läggs in vid start, det som finns rörs inte. Servern prövar varje skrivning – ett möte med egen sida eller löpande, länkar från roten – och en uppgift tas aldrig bort.
ADR-037 | En ändringslogg i startsidans databas | Antagen | Att göra-listans SQLite-fil blir startsidans databas, DATABAS_FIL, med ett schema som växer i numrerade steg; den gamla filen kopieras in en gång. En tabell andringar får en rad för varje ändring – statusrapporter, uppgifter och nya byggen – skriven av den som ändrar. Uppgifternas rader är inte publika: till chatten går bara statusrapporterna. Den tekniska tidslinjen är /andringar bakom åtkomstkoden, och varje uppgift visar sina rader. Notiserna till teamschatten ska läsa loggen i ett senare steg, och då bara statusrapporterna.
ADR-038 | Funktionerna läggs till på sidan och via API, och bor i databasen | Antagen | Funktionerna på /funktioner bor i startsidans databas; funktioner.ts är startdata. Ett nytt läge, Önskemål, för det som kommit in men inte prövats. Den som har skrivnyckeln lägger till och ändrar på sidan, och API:t /api/funktioner tar emot POST, PUT och PATCH med skrivnyckeln som Bearer-token – vägen för en agent att lägga upp något i produktion. GET är öppet. Servern prövar varje skrivning, ger id:t ur namnet och tar aldrig bort en funktion; varje ändring loggas.
ADR-039 | Konton för projektgruppen – användarnamn och lösenord, först för att göra-listan | Antagen | Projektgruppen får egna konton med användarnamn och lösenord, som en mellanlösning tills SAML-sessionen i fas 4; åtkomstkoden är fortfarande ingen identitet. Två roller, medlem och admin. Admin skapar konton på /konton med ett engångslösenord som byts vid första inloggningen; det första kontot skapas med skrivnyckeln. Engångslösenordet gäller i sju dagar. Lösenorden sparas som scrypt med OWASP:s parametrar och prövas mot vanliga lösenord; tio fel i rad spärrar kontot i en kvart. Sessionen gäller i 90 dagar och förnyas när den används (ändrat 20 oktober 2026), med bara kakans fingeravtryck i databasen. Ett konto stängs men tas aldrig bort. Ändringsloggen får kolumnen av, som visas bara för inloggade. Först för att göra-listan; statusrapporterna, funktionerna och API:erna behåller skrivnyckeln.
ADR-040 | Projektportalen och startsideportalen är två applikationer på en domän | Antagen | start.sundsvall.dev rymmer två applikationer med olika syften: projektportalen, projektet om startsidan, och startsideportalen, prototypen av själva produkten. De delar domän för användarnas skull, inte för att de hör ihop. Allt som hör till prototypen ska ligga under /portal, också devportalen som blir /portal/dev; allt annat är projektportalen. CLAUDE.md delas i gemensamt, projektportalen och startsideportalen, och ingen identitet korsar gränsen. Koden delas i steg enligt docs/plan-uppdelning.md – fas 6 i planen – när projektet är redo.
## Öppna frågor
- Flödesmotorns kontrakt (ADR-005) skrivs i M4. Acceptanskriteriet är att ett andra flöde kan definieras på under en timme utan ny UI-kod.
- Största risken är fortfarande att modulkontraktet blir fel dimensionerat – för tunt och skalet måste ändras för varje modul, för tjockt och det blir byråkrati.
- Nya fält i ModuleManifest ska bäras av minst två moduler innan de blir permanenta.
- Intranätets Sitevision som källa för Sidor: samma headless-API som sundsvall.se, men bakom inloggning. Kräver servicekonto via BFF eller WSO2 i fas 4 (ADR-016).
- Vilket innehåll hör hemma på intranätet? Spiken visar skolavtalet från sundsvall.se för att pröva kontraktet, inte för att det är rätt innehåll.
- /dev/beslut — ADR-001 – App Router istället för Pages Router (docs/beslut/ADR-001-app-router.md)
- /dev/beslut — ADR-002 – Egen designgrund istället för @sk-web-gui (docs/beslut/ADR-002-egen-designgrund.md)
- /dev/beslut — ADR-003 – "Sidor" är en egen sidtyp (docs/beslut/ADR-003-sidor-som-sidtyp.md)
- /dev/beslut — ADR-004 – routes + fokusläge i ModuleManifest (docs/beslut/ADR-004-routes-och-fokuslage.md)
- /dev/beslut — ADR-005 – Flödesmotorns kontrakt (docs/beslut/ (ännu inte skriven))
- /dev/beslut — ADR-006 – Rollen i cookie; moduler hämtar egen data (docs/beslut/ADR-006-roll-i-cookie.md)
- /dev/beslut — ADR-007 – Aggregerande moduler (docs/beslut/ADR-007-aggregerande-moduler.md)
- /dev/beslut — ADR-008 – shadcn/ui som komponentgrund (docs/beslut/ADR-008-shadcn-som-komponentgrund.md)
- /dev/beslut — ADR-009 – Designsystemet som data (docs/beslut/ADR-009-designsystem-som-data.md)
- /dev/beslut — ADR-010 – Devportalen som ingång för människa och agent (docs/beslut/ADR-010-devportal.md)
- /dev/beslut — ADR-011 – Dokumentation som leveransvillkor (docs/beslut/ADR-011-dokumentation-som-leveransvillkor.md)
- /dev/beslut — ADR-012 – Åtkomstkod som demospärr (docs/beslut/ADR-012-atkomstkod.md)
- /dev/beslut — ADR-014 – Portalens påståenden verifieras (docs/beslut/ADR-014-portalen-verifieras.md)
- /dev/beslut — ADR-013 – Signerad fältförankring mellan turer (docs/beslut/ADR-013-signerad-faltforankring.md)
- /dev/beslut — ADR-015 – Dokumentflöden definieras som data i modulen (docs/beslut/ADR-015-dokumentflode.md)
- /dev/beslut — ADR-016 – PageManifest med källoberoende innehåll (docs/beslut/ADR-016-sidor-med-extern-kalla.md)
- /dev/beslut — ADR-017 – En Sitevision-webbplats inramad i skalet (docs/beslut/ADR-017-inramad-webbplats.md)
- /dev/beslut — ADR-018 – Användaren ordnar korten på startsidan (docs/beslut/ADR-018-anpassningsbar-startsida.md)
- /dev/beslut — ADR-019 – Modulvyer med skalets krom och vägparametrar (docs/beslut/ADR-019-modulvyer-med-skalets-krom.md)
- /dev/beslut — ADR-020 – Notiserna kommer från modulerna och leder till funktioner (docs/beslut/ADR-020-notiser-fran-modulerna.md)
- /dev/beslut — ADR-021 – Fokusytan under AI-fältet på startsidan (docs/beslut/ADR-021-fokusyta.md)
- /dev/beslut — ADR-022 – Ingångens egna kort och hopfällbara block – IT-support som första sida (docs/beslut/ADR-022-ingangens-kort-och-block.md)
- /dev/beslut — ADR-023 – Min AI – en personlig assistent med Eneos sessionskontrakt (docs/beslut/ADR-023-min-ai.md)
- /dev/beslut — ADR-024 – Verktyg, skills och MCP-tjänster i Min AI (docs/beslut/ADR-024-min-ai-verktyg.md)
- /dev/beslut — ADR-025 – Modulvyer över hela arbetsytan, och genvägar bredvid hälsningen (docs/beslut/ADR-025-hel-arbetsyta.md)
- /dev/beslut — ADR-026 – AI tonas i blått, inte grönt – grönt är bara status (docs/beslut/ADR-026-ai-i-blatt.md)
- /dev/beslut — ADR-027 – Målgruppsingång – Verktygslådan under Digitalisering, IT och AI (docs/beslut/ADR-027-malgruppsingang.md)
- /dev/beslut — ADR-028 – Workshoprösten – röstkoder utanför spärren, prickar i en fil (docs/beslut/ADR-028-workshoprost.md)
- /dev/beslut — ADR-029 – Projektets sida på roten, prototypen på /portal (docs/beslut/ADR-029-projektsidan-pa-roten.md)
- /dev/beslut — ADR-030 – Kompetens är ett register, inte ett LMS (docs/beslut/ADR-030-kompetens-som-register.md)
- /dev/beslut — ADR-031 – Projektboken ordnas efter typ, inte efter tillfälle (docs/beslut/ADR-031-projektboken-ordnas-efter-typ.md)
- /dev/beslut — ADR-032 – Projektet är roten, med statusrapporter och funktionerna (docs/beslut/ADR-032-projektet-ar-roten.md)
- /dev/beslut — ADR-033 – Projektets meny är en klassisk huvudmeny enligt WCAG 2.2 AA (docs/beslut/ADR-033-huvudmeny-enligt-wcag.md)
- /dev/beslut — ADR-034 – Projektstödet svarar bara utifrån projektets öppna sidor (docs/beslut/ADR-034-projektstodet.md)
- /dev/beslut — ADR-035 – Notiser till teamschatten via ett flöde i Power Automate, avstängda tills de slås på (docs/beslut/ADR-035-teamsnotiser.md)
- /dev/beslut — ADR-036 – Att göra-listan redigeras på sidan och bor i en SQLite-fil (docs/beslut/ADR-036-att-gora-i-databas.md)
- /dev/beslut — ADR-037 – En ändringslogg i startsidans databas (docs/beslut/ADR-037-andringslogg.md)
- /dev/beslut — ADR-038 – Funktionerna läggs till på sidan och via API, och bor i databasen (docs/beslut/ADR-038-funktioner-i-databas.md)
- /dev/beslut — ADR-039 – Konton för projektgruppen – användarnamn och lösenord, först för att göra-listan (docs/beslut/ADR-039-konton-for-projektgruppen.md)
- /dev/beslut — ADR-040 – Projektportalen och startsideportalen är två applikationer på en domän (docs/beslut/ADR-040-tva-applikationer-en-doman.md)Hela portalen i samma form: /dev/llms.txt · /dev/spec.json