build: a reply in the wrong language keeps the words it had; the vel's mails

A model asked for Norwegian sometimes answers in English. The commonest
function words of each language are counted across a reply, and one
that reads as the other language is refused with a line saying so.
Tomter Vel's six mails, worded by Sonnet in Norwegian, are round 2 of
runs/tomtervel-opener-2026-09-23 and live.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Bendik Aagaard Lynghaug
2026-09-23 23:35:32 +02:00
co-authored by Claude Fable 5.1
parent 72a081ed59
commit 8c7fb870bf
6 changed files with 1153 additions and 54 deletions
@@ -24,3 +24,14 @@ opener picks as misroutes; it is kept for the record.
Level with the live site within the visitor's noise, with everything Level with the live site within the visitor's noise, with everything
new on top. Merged to tomtervel/questions main the same evening. The new on top. Merged to tomtervel/questions main the same evening. The
mails are the builder's fallbacks; a model has not reworded them. mails are the builder's fallbacks; a model has not reworded them.
## Round 2: the mails, in Norwegian
`build --llm-for aggregates.yaml` with Sonnet, every other word as
merged. Six mails, all in Norwegian, both links to the sender's own
move kept (the builder puts a lost link back). Readability level with
the fallbacks, LIX 7 to 33 against 13 to 20, and the text says what
happened: "Vi har funnet en nabo som kan hjelpe. De tar kontakt med
deg direkte." On vel.klingenbergbygg.no the same evening. The builder
now refuses a reply in the wrong language for the plan and keeps the
words it had.
@@ -38,38 +38,24 @@ aggregates:
event: formidlet event: formidlet
mail: mail:
body: |- body: |-
Hei, Vi har funnet en nabo som kan hjelpe. De tar kontakt med deg direkte.
Det du sendte om at en nabo stiller opp er nå formidlet.
Det du kan gjøre nå: {site}/decide/trenger-hjelp?chain={chain}&email={email} Det du kan gjøre nå: {site}/decide/trenger-hjelp?chain={chain}&email={email}
subject: En nabo er koblet på
Styret i Tomter Vel på post@tomtervel.no
subject: 'Tomter Vel: Formidlet'
to: submitter to: submitter
ikke_lost: ikke_lost:
event: ikke_lost event: ikke_lost
open: open:
event: received event: received
mail: mail:
body: |- body: Vi har mottatt det du trenger hjelp til, og ser etter en nabo som kan stille opp. Du hører fra oss så snart vi har funnet noen.
Hei, subject: Vi leter etter en nabo til deg
Vi har mottatt det du sendte om at en nabo stiller opp.
Styret i Tomter Vel på post@tomtervel.no
subject: 'Tomter Vel: Open'
to: submitter to: submitter
ordnet: ordnet:
event: ordnet event: ordnet
mail: mail:
body: |- body: Godt å høre at det ordnet seg. Takk for at du sa fra, og lykke til videre.
Hei, subject: Bra det løste seg
Det du sendte om at en nabo stiller opp er nå ordnet.
Styret i Tomter Vel på post@tomtervel.no
subject: 'Tomter Vel: Ordnet'
to: submitter to: submitter
transitions: transitions:
formidlet: formidlet:
@@ -97,26 +83,17 @@ aggregates:
betalt: betalt:
event: betalt event: betalt
mail: mail:
body: |- body: Kontingenten er registrert betalt. Du er nå medlem av Tomter Vel - velkommen med!
Hei, subject: Medlemskapet er i orden
Det du sendte om å bli medlem og få betalt kontingenten er nå betalt.
Styret i Tomter Vel på post@tomtervel.no
subject: 'Tomter Vel: Betalt'
to: submitter to: submitter
open: open:
event: received event: received
mail: mail:
body: |- body: |-
Hei, Takk for at du vil bli medlem. Du får en betalingsoppfordring med kontonummer og beløp så snart kasserer har sett på saken.
Vi har mottatt det du sendte om å bli medlem og få betalt kontingenten.
Det du kan gjøre nå: {site}/decide/bli-medlem?chain={chain}&email={email} Det du kan gjøre nå: {site}/decide/bli-medlem?chain={chain}&email={email}
subject: Nesten i mål som medlem
Styret i Tomter Vel på post@tomtervel.no
subject: 'Tomter Vel: Open'
to: submitter to: submitter
utmeldt: utmeldt:
event: utmeldt event: utmeldt
@@ -166,13 +143,8 @@ aggregates:
lagt_ut: lagt_ut:
event: lagt_ut event: lagt_ut
mail: mail:
body: |- body: Oppslaget ditt er lagt ut, og naboene kan nå se det.
Hei, subject: Oppslaget er synlig for naboene
Det du sendte om et oppslag som naboene ser er nå lagt ut.
Styret i Tomter Vel på post@tomtervel.no
subject: 'Tomter Vel: Lagt ut'
to: submitter to: submitter
open: open:
event: received event: received
@@ -0,0 +1,108 @@
You write the words for one page of a website for this business.
Business: Tomter Vel
About: Velforeningen for Tomter, stiftet i 1947. Sju komiteer drevet på fritida: arrangementer, elvestien, lekeplassene, høringssvar, miljøgata, pendlerforhold og trafikk. 157 husstander er medlemmer.
Contact: Styret i Tomter Vel <post@tomtervel.no>
Language to write in: no
Everyone the site serves:
- door medlem: for en husstand i Tomter som vil bli medlem, betale kontingent, eller melde flytting, ny e-post eller utmelding; behind it: bli-medlem, endre-medlemskap
- door melde-fra: for noen som har sett noe farlig i trafikken, eller noe ødelagt på lekeplassen eller stien; behind it: trafikkfare, anleggsfeil
- door bidra: for noen som vil stille opp på 17. mai, dugnad eller et arrangement, eller sitte i en komité; behind it: hjelpe-til, komite
- door naboer: for en nabo som trenger en hånd med snømåking, handling eller skyss, kan gi en, eller har noe å låne ut; behind it: trenger-hjelp, kan-hjelpe, dele-utstyr
- bli-medlem: en husstand i Tomter - wants: å bli medlem og få betalt kontingenten. Handled by kasserer. Stages: open -> betalt -> utmeldt.
- endre-medlemskap: et medlem som har flyttet, byttet e-post eller vil melde seg ut - wants: at velet har riktige opplysninger om dem. Handled by kasserer. Stages: open -> oppdatert.
- trafikkfare: en som har sett et farlig sted i trafikken - wants: at velet tar det opp med kommunen eller den som eier veien. Handled by trafikk. Stages: open -> tatt_opp -> ordnet -> avvist.
- anleggsfeil: en som ser at noe på lekeplassen eller stien er ødelagt - wants: at det blir fikset før noen skader seg. Handled by lekeplasser. Stages: open -> tatt_tak_i -> utbedret.
- horingsinnspill: en beboer som har en mening om en sak kommunen har på høring - wants: at velet tar det med i sitt svar. Handled by horingsinstans. Stages: open -> tatt_med -> ikke_tatt_med.
- hjelpe-til: en som vil hjelpe til på et arrangement eller en dugnad - wants: å bli satt opp på noe som passer dem. Handled by arrangementer. Stages: open -> kontaktet -> satt_opp -> takket_nei.
- komite: en som vil sitte i en komité - wants: en plass i den komiteen som driver med det de bryr seg om. Handled by styret. Stages: open -> plassert -> avslatt.
- trenger-hjelp: en beboer som ikke får til noe selv for tiden, som snømåking, handling eller en skyss - wants: at en nabo stiller opp. Handled by nabohjelp. Stages: open -> formidlet -> ordnet -> ikke_lost.
- kan-hjelpe: en nabo som kan stille opp når noen trenger det - wants: å bli spurt når det passer. Handled by nabohjelp. Stages: open -> registrert -> trukket.
- dele-utstyr: en nabo som har noe å låne ut, eller trenger å låne noe - wants: et oppslag som naboene ser. Handled by styret. Stages: open -> lagt_ut -> tatt_ned.
- utlegg: en i en komité som har lagt ut for noe - wants: pengene tilbake. Handled by kasserer. Stages: open -> godkjent -> utbetalt -> avvist.
The page: aggregates.yaml
It is the mails the site sends. Under each bucket, each stage that sends one has a `subject` and a `body`: the mail a person gets the moment their case enters that stage, saying what happened and what, if anything, they can do now. Plain text, short, in the business's voice. Keep every `{...}` placeholder exactly as it is - `{site}`, `{chain}`, `{email}` and any field name are filled in by the site - and keep any line with a link in it.
Below is the page as JSON. Every value is a slot that says what to write there. Return the same JSON with every slot replaced by your words. Keep every key exactly as it is. A slot left as it is counts as no answer.
Rules for the words:
- `question` is a question the reader could ask themselves.
- A heading says what the reader gets, in the reader's own words, and must work without its description.
- Lead with what a thing enables. No negations in headings. No trade jargon the reader would not use.
- Descriptions are one or two short sentences. Labels and buttons are a few words.
- The button says what pressing it does; the encouragement says what happens next or how little it takes; the form's guidance line says what to have ready. Placeholders are example answers in the reader's words.
- An icon is one name from this list, chosen for what the reader is doing, or empty: house, building-2, store, school, map-pin, route, footprints, trees, leaf, snowflake, sun, users, user, user-plus, user-check, baby, heart-handshake, hand-helping, handshake, smile, mail, phone, message-circle, megaphone, bell, send, inbox, alert-triangle, siren, shield, construction, hammer, wrench, ruler, package, truck, car, bus, train-front, bike, calendar, clock, file-text, clipboard-list, receipt, wallet, coins, banknote, credit-card, key, lock, search, star, gift, shopping-cart, lightbulb, flag, thumbs-up, check-circle, briefcase, stethoscope, activity, camera, pencil, refresh-cw, list, layers, vote, scale
- Write the way people in this trade and country actually speak.
{
"hjelpebehov": {
"formidlet": {
"body": "<WRITE: a form label for the field `body`>",
"subject": "<WRITE: a form label for the field `subject`>"
},
"open": {
"body": "<WRITE: a form label for the field `body`>",
"subject": "<WRITE: a form label for the field `subject`>"
},
"ordnet": {
"body": "<WRITE: a form label for the field `body`>",
"subject": "<WRITE: a form label for the field `subject`>"
}
},
"husstander": {
"betalt": {
"body": "<WRITE: a form label for the field `body`>",
"subject": "<WRITE: a form label for the field `subject`>"
},
"open": {
"body": "<WRITE: a form label for the field `body`>",
"subject": "<WRITE: a form label for the field `subject`>"
}
},
"oppslag": {
"lagt_ut": {
"body": "<WRITE: a form label for the field `body`>",
"subject": "<WRITE: a form label for the field `subject`>"
}
}
}
Reply with the JSON object only.
=== REPLY ===
```json
{
"hjelpebehov": {
"formidlet": {
"body": "Vi har funnet en nabo som kan hjelpe. De tar kontakt med deg direkte.",
"subject": "En nabo er koblet på"
},
"open": {
"body": "Vi har mottatt det du trenger hjelp til, og ser etter en nabo som kan stille opp. Du hører fra oss så snart vi har funnet noen.",
"subject": "Vi leter etter en nabo til deg"
},
"ordnet": {
"body": "Godt å høre at det ordnet seg. Takk for at du sa fra, og lykke til videre.",
"subject": "Bra det løste seg"
}
},
"husstander": {
"betalt": {
"body": "Kontingenten er registrert betalt. Du er nå medlem av Tomter Vel - velkommen med!",
"subject": "Medlemskapet er i orden"
},
"open": {
"body": "Takk for at du vil bli medlem. Du får en betalingsoppfordring med kontonummer og beløp så snart kasserer har sett på saken.",
"subject": "Nesten i mål som medlem"
}
},
"oppslag": {
"lagt_ut": {
"body": "Oppslaget ditt er lagt ut, og naboene kan nå se det.",
"subject": "Oppslaget er synlig for naboene"
}
}
}
```
@@ -2,32 +2,32 @@
"aggregates.yaml": { "aggregates.yaml": {
"hjelpebehov": { "hjelpebehov": {
"formidlet": { "formidlet": {
"body": "Hei,\n\nDet du sendte om at en nabo stiller opp er nå formidlet.\n\nDet du kan gjøre nå: {site}/decide/trenger-hjelp?chain={chain}&email={email}\n\nStyret i Tomter Vel på post@tomtervel.no", "body": "Vi har funnet en nabo som kan hjelpe. De tar kontakt med deg direkte.\n\nDet du kan gjøre nå: {site}/decide/trenger-hjelp?chain={chain}&email={email}",
"subject": "Tomter Vel: Formidlet" "subject": "En nabo er koblet på"
}, },
"open": { "open": {
"body": "Hei,\n\nVi har mottatt det du sendte om at en nabo stiller opp.\n\nStyret i Tomter Vel på post@tomtervel.no", "body": "Vi har mottatt det du trenger hjelp til, og ser etter en nabo som kan stille opp. Du hører fra oss så snart vi har funnet noen.",
"subject": "Tomter Vel: Open" "subject": "Vi leter etter en nabo til deg"
}, },
"ordnet": { "ordnet": {
"body": "Hei,\n\nDet du sendte om at en nabo stiller opp er nå ordnet.\n\nStyret i Tomter Vel på post@tomtervel.no", "body": "Godt å høre at det ordnet seg. Takk for at du sa fra, og lykke til videre.",
"subject": "Tomter Vel: Ordnet" "subject": "Bra det løste seg"
} }
}, },
"husstander": { "husstander": {
"betalt": { "betalt": {
"body": "Hei,\n\nDet du sendte om å bli medlem og få betalt kontingenten er nå betalt.\n\nStyret i Tomter Vel på post@tomtervel.no", "body": "Kontingenten er registrert betalt. Du er nå medlem av Tomter Vel - velkommen med!",
"subject": "Tomter Vel: Betalt" "subject": "Medlemskapet er i orden"
}, },
"open": { "open": {
"body": "Hei,\n\nVi har mottatt det du sendte om å bli medlem og få betalt kontingenten.\n\nDet du kan gjøre nå: {site}/decide/bli-medlem?chain={chain}&email={email}\n\nStyret i Tomter Vel på post@tomtervel.no", "body": "Takk for at du vil bli medlem. Du får en betalingsoppfordring med kontonummer og beløp så snart kasserer har sett på saken.\n\nDet du kan gjøre nå: {site}/decide/bli-medlem?chain={chain}&email={email}",
"subject": "Tomter Vel: Open" "subject": "Nesten i mål som medlem"
} }
}, },
"oppslag": { "oppslag": {
"lagt_ut": { "lagt_ut": {
"body": "Hei,\n\nDet du sendte om et oppslag som naboene ser er nå lagt ut.\n\nStyret i Tomter Vel på post@tomtervel.no", "body": "Oppslaget ditt er lagt ut, og naboene kan nå se det.",
"subject": "Tomter Vel: Lagt ut" "subject": "Oppslaget er synlig for naboene"
} }
} }
}, },
@@ -0,0 +1,953 @@
{
"aggregates.yaml": {
"hjelpebehov": {
"formidlet": {
"body": "Vi har funnet en nabo som kan hjelpe. De tar kontakt med deg direkte.\n\nDet du kan gjøre nå: {site}/decide/trenger-hjelp?chain={chain}&email={email}",
"subject": "En nabo er koblet på"
},
"open": {
"body": "Vi har mottatt det du trenger hjelp til, og ser etter en nabo som kan stille opp. Du hører fra oss så snart vi har funnet noen.",
"subject": "Vi leter etter en nabo til deg"
},
"ordnet": {
"body": "Godt å høre at det ordnet seg. Takk for at du sa fra, og lykke til videre.",
"subject": "Bra det løste seg"
}
},
"husstander": {
"betalt": {
"body": "Kontingenten er registrert betalt. Du er nå medlem av Tomter Vel - velkommen med!",
"subject": "Medlemskapet er i orden"
},
"open": {
"body": "Takk for at du vil bli medlem. Du får en betalingsoppfordring med kontonummer og beløp så snart kasserer har sett på saken.\n\nDet du kan gjøre nå: {site}/decide/bli-medlem?chain={chain}&email={email}",
"subject": "Nesten i mål som medlem"
}
},
"oppslag": {
"lagt_ut": {
"body": "Oppslaget ditt er lagt ut, og naboene kan nå se det.",
"subject": "Oppslaget er synlig for naboene"
}
}
},
"questions/arrangementer/index.yaml": {
"buckets": {
"frivillige": {
"description": "Her ser du hvem som har meldt seg til dugnad, 17. mai eller andre arrangementer, og hvor langt du har kommet med hver av dem.",
"heading": "Frivillige til arrangementer og dugnad",
"moves": {
"kontaktet->satt_opp": "Sett opp",
"kontaktet->takket_nei": "Takket nei",
"open->kontaktet": "Merk som kontaktet",
"open->takket_nei": "Takket nei"
}
}
},
"confirm": "Lagre",
"description": "Oversikt over folk som vil hjelpe til, slik at du kan følge opp og sette dem opp på noe som passer.",
"invited": {
"description": "Hver invitasjon med lenken som ble laget. Marker som ferdig når personen er inne.",
"done": "Er inne",
"heading": "Sendte invitasjoner"
},
"invites": {
"arrangementer": {
"button": "Inviter",
"description": "De får en konto, plass i Arrangementer, og en engangslenke der de selv velger passord eller passnøkkel. Send lenken videre til dem.",
"form_title": "Hvem",
"heading": "Inviter noen inn i Arrangementer",
"labels": {
"email": "E-post",
"name": "Navn"
}
}
},
"links": {},
"question": "Hvem har meldt seg, og hvor langt har jeg kommet med å sette dem opp?"
},
"questions/bidra/index.yaml": {
"description": "Vil du stille opp for nabolaget? Her melder du deg til dugnad og arrangementer, eller til en av komiteene.",
"needs": {
"hjelpe-til": {
"button": "Meld meg på",
"description": "17. mai, dugnad eller andre arrangementer trenger folk som stiller opp. Si fra hva du kan bidra med, så setter vi deg opp på noe som passer.",
"encouragement": "Det holder med noen ord om hva du kan tenke deg – vi tar kontakt når det nærmer seg.",
"form_description": "Fortell kort hva du kan hjelpe til med.",
"form_title": "Meld deg som hjelper",
"heading": "Bli med på dugnad eller arrangement",
"hints": {
"hva": "",
"navn": "Kari Nordmann",
"telefon": "912 34 567"
},
"icon": "hand-helping",
"labels": {
"hva": "Hva kan du hjelpe til med?",
"navn": "Navn",
"telefon": "Telefon"
},
"road_description": "Arrangementskomiteen tar kontakt og finner ut hva som passer for deg. Sier du ja, blir du satt opp på en oppgave – sier du nei takk, er det helt greit.",
"road_icon": "lucide:clipboard-list",
"road_title": "Hva skjer videre",
"who_description": "Arrangementskomiteen leser det du sender, og du kan nå dem på post@tomtervel.no i mellomtiden.",
"who_icon": "lucide:users",
"who_title": "Hvem leser dette"
},
"komite": {
"button": "Meld interesse",
"description": "Velet drives av sju komiteer på fritida, og alle trenger flere hender. Si hvilken komité du har lyst til å være med i.",
"encouragement": "Det tar bare et minutt, og noen fra styret svarer deg.",
"form_description": "Skriv hvilken komité du er interessert i.",
"form_title": "Meld deg til en komité",
"heading": "Sitt i en komité som betyr noe for deg",
"hints": {
"epost": "kari@eksempel.no",
"komite": "",
"navn": "Kari Nordmann"
},
"icon": "users",
"labels": {
"epost": "E-post",
"komite": "Hvilken komité?",
"navn": "Navn"
},
"road_description": "Styret ser på ønsket ditt og finner en plass i komiteen du har meldt deg til, eller sier fra hvis det ikke er rom akkurat nå.",
"road_icon": "lucide:clipboard-list",
"road_title": "Hva skjer videre",
"who_description": "Styret leser det du sender, og du kan nå dem på post@tomtervel.no i mellomtiden.",
"who_icon": "lucide:handshake",
"who_title": "Hvem leser dette"
}
},
"question": "Vil du hjelpe til i nabolaget?"
},
"questions/decide/bli-medlem.yaml": {
"description": "",
"moves": {
"utmeldt": {
"button": "Utmeldt",
"description": "",
"heading": "Utmeldt"
}
},
"question": "What would you like to do?"
},
"questions/decide/dele-utstyr.yaml": {
"description": "Her sier du fra at utstyret er hentet eller ikke lenger tilgjengelig for utlån.",
"moves": {
"tatt_ned": {
"button": "Ta ned oppslaget",
"description": "Oppslaget fjernes fra siden, så ingen flere spør om å låne det.",
"heading": "Meld at utstyret er tatt ned"
}
},
"question": "Skal oppslaget om utstyret fortsatt stå ute?"
},
"questions/decide/kan-hjelpe.yaml": {
"description": "Her ser du naboer som har bedt om en hånd, og kan velge om du fortsatt kan bidra eller trekke deg for nå.",
"moves": {
"trukket": {
"button": "Trekk meg",
"description": "Du blir tatt av lista over naboer som kan spørres, men kan melde deg på igjen når det passer bedre.",
"heading": "Ta en pause fra nabohjelpen"
}
},
"question": "Vil du fortsatt kunne bli spurt om å hjelpe en nabo?"
},
"questions/decide/trenger-hjelp.yaml": {
"description": "Her ser du henvendelsen fra naboen som trengte en hånd, og kan si fra når det er ordnet.",
"moves": {
"ordnet": {
"button": "Merk som ordnet",
"description": "Da vet vi at naboen har fått hjelpen sin, og saken lukkes.",
"heading": "Meld fra at hjelpen er gitt"
}
},
"question": "Har naboen fått hjelpen de trengte?"
},
"questions/horingsinstans/index.yaml": {
"buckets": {
"innspill": {
"description": "Her ligger innspill fra beboere til saker kommunen har på høring.",
"heading": "Innspill til høringssvar",
"moves": {
"open->ikke_tatt_med": "Ikke tatt med",
"open->tatt_med": "Tatt med i svaret"
}
}
},
"confirm": "Send svar",
"description": "Her samler du innspillene og ser hva som er tatt med i velets høringssvar.",
"invited": {
"description": "Hver invitasjon med lenken som ble laget. Marker som ferdig når personen er inne.",
"done": "Er inne",
"heading": "Sendte invitasjoner"
},
"invites": {
"horingsinstans": {
"button": "Inviter",
"description": "De får en konto, plass i Høringsinstans, og en engangslenke der de selv velger passord eller passnøkkel. Send lenken videre til dem.",
"form_title": "Hvem",
"heading": "Inviter noen inn i Høringsinstans",
"labels": {
"email": "E-post",
"name": "Navn"
}
}
},
"links": {},
"question": "Hva sier vi i høringssvaret?"
},
"questions/index.yaml": {
"description": "Velforeningen for Tomter, stiftet i 1947, drevet på fritida av naboene dine. Alt du kan be om her havner hos en komité eller styret, og du ser selv hvor saken står.",
"doors": {
"bidra": {
"button": "Bli med",
"description": "Vi trenger folk på 17. mai, dugnader og i komiteene. Det trengs ikke mer enn litt tid du har å avse.",
"for_whom": "Deg som vil gjøre en innsats",
"heading": "Bli med og gjør en innsats",
"icon": "hand-helping"
},
"medlem": {
"button": "Til medlemskap",
"description": "Meld deg inn, betal kontingenten, eller gi beskjed om flytting, ny e-post eller utmelding.",
"for_whom": "Deg som bor i Tomter",
"heading": "Bli medlem eller endre opplysningene dine",
"icon": "house"
},
"melde-fra": {
"button": "Meld fra",
"description": "Sett du noe farlig i trafikken, eller noe ødelagt på lekeplassen eller elvestien? Gi oss beskjed.",
"for_whom": "Deg som har sett noe som bør fikses",
"heading": "Meld fra om noe som bør fikses",
"icon": "alert-triangle"
},
"naboer": {
"button": "Til nabohjelp",
"description": "Trenger du en hånd med snømåking, handling eller skyss? Eller kan du stille opp for en nabo? Her møtes dere.",
"for_whom": "Deg som trenger hjelp eller kan gi en hånd",
"heading": "Få hjelp av naboer, eller gi en hånd selv",
"icon": "heart-handshake"
}
},
"needs": {
"horingsinnspill": {
"button": "Send innspill",
"description": "Har kommunen en sak på høring du mener noe om? Send oss innspillet ditt, så tar vi det med i velets svar.",
"encouragement": "Innspillet ditt blir lest av høringsutvalget vårt og veier inn i svaret vi sender kommunen.",
"form_description": "Fortell hvilken sak det gjelder og hva du mener.",
"form_title": "Send et høringsinnspill",
"heading": "Få din mening med i høringssvaret",
"hints": {
"innspill": "Jeg mener det bør settes opp fartsdumper langs den nye traseen, for barna krysser der til skolen.",
"navn": "Kari Nordmann",
"sak": "Reguleringsplan for Tomterveien"
},
"icon": "megaphone",
"labels": {
"innspill": "Hva mener du?",
"navn": "Navn",
"sak": "Hvilken sak gjelder det?"
},
"road_description": "Innspillet ditt kommer inn hos høringsutvalget. De vurderer om det tas med i velets svar til kommunen, eller om det ikke passer inn denne gangen.",
"road_icon": "lucide:route",
"road_title": "Hva skjer videre",
"who_description": "Høringsutvalget i Tomter Vel leser innspillet ditt; i mellomtiden kan du nå styret på post@tomtervel.no.",
"who_icon": "lucide:users",
"who_title": "Hvem leser dette"
}
},
"opener": {
"description": "To ting først. Resten står lenger ned på siden.",
"features": {
"medlem": {
"description": "Velet taler for Tomter overfor kommunen, holder lekeplassene og stien i stand og samler naboene på 17. mai og dugnad. 157 husstander er med. Du melder deg inn her, og ut igjen selv når du vil.",
"heading": "Et vel som taler for Tomter, og et medlemskap du styrer selv",
"icon": "users"
},
"nabo": {
"description": "Trenger du en hånd med snømåking, handling eller skyss, kobler nabohjelpsgruppa deg med en nabo som kan. Du sier selv fra når det er ordnet.",
"heading": "En nabo som stiller opp når du trenger det",
"icon": "handshake"
}
},
"heading": "Dette gjør velet"
},
"question": "Hva gjør Tomter Vel, og hva kan du få her?",
"shopping": {
"description": "Ingenting å fylle ut her. Det som er meldt inn, og hvor hver sak står.",
"heading": "Se deg rundt først",
"items": {
"status-anleggsfeil": {
"description": "Lekeplassen og stien: det som er meldt, og det som er fikset.",
"heading": "Alt som er meldt ødelagt",
"icon": "list"
},
"status-oppslag": {
"description": "Det naboene har å låne ut, og det de trenger å låne.",
"heading": "Oppslagstavla",
"icon": "list"
},
"status-trafikkmeldinger": {
"description": "Farlige steder naboene har meldt, og hva velet har gjort med dem.",
"heading": "Alle trafikkmeldinger",
"icon": "list"
}
}
}
},
"questions/kasserer/index.yaml": {
"buckets": {
"husstander": {
"description": "Husstander som har meldt seg inn og venter på å bli registrert som betalende medlem.",
"heading": "Nye medlemmer som venter på registrering",
"moves": {
"open->betalt": "Registrer betaling",
"open->utmeldt": "Meld ut"
}
},
"medlemsendringer": {
"description": "Medlemmer som har flyttet, byttet e-post eller vil melde seg ut, og venter på at opplysningene blir oppdatert.",
"heading": "Endringer som venter på å bli registrert",
"moves": {
"open->oppdatert": "Registrer endring"
}
},
"utlegg": {
"description": "Utlegg fra komitémedlemmer som venter på godkjenning eller utbetaling.",
"heading": "Utlegg som venter på deg",
"moves": {
"godkjent->avvist": "Avvis likevel",
"godkjent->utbetalt": "Merk som utbetalt",
"open->avvist": "Avvis utlegg",
"open->godkjent": "Godkjenn utlegg"
}
}
},
"confirm": "Lagre",
"description": "Her har du oversikt over medlemmer, endringer og utlegg som venter på deg som kasserer.",
"invited": {
"description": "Hver invitasjon med lenken som ble laget. Marker som ferdig når personen er inne.",
"done": "Er inne",
"heading": "Sendte invitasjoner"
},
"invites": {
"kasserer": {
"button": "Inviter",
"description": "De får en konto, plass i kassereren, og en engangslenke der de selv velger passord eller passnøkkel. Send lenken videre til dem.",
"form_title": "Hvem",
"heading": "Inviter noen inn i kassereren",
"labels": {
"email": "E-post",
"name": "Navn"
}
}
},
"links": {},
"question": "Hva venter på meg som kasserer akkurat nå?"
},
"questions/komiteer/index.yaml": {
"buckets": {},
"confirm": "Confirm",
"description": "Her holder du oversikt over sakene komiteen din har ansvar for, og flytter dem videre etter hvert som de blir fulgt opp.",
"invited": {
"description": "Hver invitasjon med lenken som ble laget. Marker som ferdig når personen er inne.",
"done": "Er inne",
"heading": "Sendte invitasjoner"
},
"invites": {
"komiteer": {
"button": "Inviter",
"description": "De får en konto, plass i komiteene, og en engangslenke der de selv velger passord eller passnøkkel. Send lenken videre til dem.",
"form_title": "Hvem",
"heading": "Inviter noen inn i komiteene",
"labels": {
"email": "E-post",
"name": "Navn"
}
}
},
"links": {
"utlegg": {
"button": "Send utlegg",
"description": "Har du lagt ut for noe til komiteen? Send det inn så kasserer kan betale deg tilbake.",
"heading": "Få tilbake det du har lagt ut"
}
},
"question": "Hva står ubehandlet i komiteen din nå?"
},
"questions/komiteer/utlegg-sent.yaml": {
"back": "Til forsiden",
"description": "Utlegget er sendt til kasserer. Du får beskjed når det er sjekket.",
"next_description": "Kasserer ser gjennom kvitteringen og overfører pengene til kontoen du oppga.",
"next_heading": "Pengene kommer på konto",
"question": "Hva skjer med utlegget mitt nå?"
},
"questions/komiteer/utlegg.yaml": {
"button": "Send inn",
"description": "Har du lagt ut for noe til komiteen? Send det inn, så ordner kasserer resten.",
"encouragement": "Legg ved bilag om du har det, så går det raskere.",
"form_description": "Ha kvittering eller bilag klart før du fyller ut.",
"form_title": "Krav om refusjon",
"heading": "Få pengene tilbake",
"hints": {
"belop": "450 kr",
"hva": "Kaffe og kjeks til dugnaden",
"navn": "Kari Nordmann"
},
"icon": "receipt",
"labels": {
"belop": "Beløp",
"hva": "Hva gjaldt det",
"navn": "Navn"
},
"page_description": "Har du betalt for noe på vegne av en komité? Send inn utlegget, så får du pengene tilbake.",
"question": "Har du lagt ut penger for komiteen og vil ha dem tilbake?",
"road_description": "Kasserer ser gjennom kravet og godkjenner det, og deretter blir pengene utbetalt til deg. Blir det avvist, hører du hvorfor.",
"road_icon": "lucide:wallet",
"road_title": "Fra krav til utbetaling",
"who_description": "Kasserer i styret leser kravet ditt, og kan nås på post@tomtervel.no om det haster.",
"who_icon": "lucide:coins",
"who_title": "Kasserer ser dette"
},
"questions/lekeplasser/index.yaml": {
"buckets": {
"anleggsfeil": {
"description": "Meldinger om noe som er ødelagt på lekeplassen eller langs stien, og som bør fikses.",
"heading": "Det som er meldt inn av skader",
"moves": {
"open->tatt_tak_i": "Ta tak i saken",
"tatt_tak_i->utbedret": "Merk som utbedret"
}
}
},
"confirm": "Lagre",
"description": "Her følger komiteen for lekeplassene opp det som er meldt inn av skader, til det er fikset.",
"invited": {
"description": "Hver invitasjon med lenken som ble laget. Marker som ferdig når personen er inne.",
"done": "Er inne",
"heading": "Sendte invitasjoner"
},
"invites": {
"lekeplasser": {
"button": "Inviter",
"description": "De får en konto, plass i Leke- og møteplasser, og en engangslenke der de selv velger passord eller passnøkkel. Send lenken videre til dem.",
"form_title": "Hvem",
"heading": "Inviter noen inn i Leke- og møteplasser",
"labels": {
"email": "E-post",
"name": "Navn"
}
}
},
"links": {},
"question": "Hva må fikses på lekeplassene og stien nå?"
},
"questions/medlem/index.yaml": {
"description": "Bli medlem av Tomter Vel, eller oppdater opplysningene dine hvis du allerede er medlem.",
"needs": {
"bli-medlem": {
"button": "Bli medlem",
"description": "Meld deg inn i velet, så holder vi deg oppdatert og du støtter arbeidet i nærmiljøet.",
"encouragement": "Kasserer sender deg kontingenten på e-post rett etterpå.",
"form_description": "Ha adressen i Tomter og en e-post du bruker klar.",
"form_title": "Meld deg inn",
"heading": "Bli medlem av Tomter Vel",
"hints": {
"adresse": "Tomterveien 12",
"email": "",
"navn": "Ola Nordmann",
"telefon": "123 45 678"
},
"icon": "user-plus",
"labels": {
"adresse": "Adresse",
"email": "Email",
"navn": "Navn",
"telefon": "Telefon"
},
"road_description": "Meldingen går til kasserer, som registrerer deg og sender deg kontingenten på e-post. Når den er betalt er du medlem.",
"road_icon": "lucide:coins",
"road_title": "Etter innmelding",
"who_description": "Kasserer i styret leser dette, og du kan nå oss på post@tomtervel.no i mellomtiden.",
"who_icon": "lucide:user",
"who_title": "Hvem svarer deg"
},
"endre-medlemskap": {
"button": "Send endring",
"description": "Har du flyttet, byttet e-post eller vil melde deg ut? Gi oss beskjed så vi har riktige opplysninger.",
"encouragement": "Det tar bare et par minutter, og kasserer ordner resten.",
"form_description": "Skriv navnet ditt og hva som er nytt.",
"form_title": "Endre medlemskap",
"heading": "Oppdater eller avslutt medlemskapet",
"hints": {
"adresse": "Ny adresse i Tomter",
"hva_er_nytt": "Ny e-post, ny adresse, eller ønske om utmelding",
"navn": "Ola Nordmann"
},
"icon": "pencil",
"labels": {
"adresse": "Adresse",
"hva_er_nytt": "Hva vil du endre?",
"navn": "Navn"
},
"road_description": "Kasserer får beskjeden og oppdaterer medlemslisten, eller melder deg ut om det er det du ber om.",
"road_icon": "lucide:refresh-cw",
"road_title": "Etter du sender inn",
"who_description": "Kasserer i styret leser dette, og du kan nå oss på post@tomtervel.no i mellomtiden.",
"who_icon": "lucide:user",
"who_title": "Hvem svarer deg"
}
},
"question": "Vil du bli medlem, eller endre medlemskapet ditt?"
},
"questions/melde-fra/index.yaml": {
"description": "Har du sett noe farlig i trafikken, eller noe ødelagt på lekeplassen eller stien? Her sier du fra til velet.",
"needs": {
"anleggsfeil": {
"button": "Send inn",
"description": "Se noe ødelagt på en lekeplass eller langs elvestien, så tar lekeplasskomiteen tak i det.",
"encouragement": "Det holder med noen ord om hva du så og hvor.",
"form_description": "Fortell hva som er ødelagt og omtrent hvor det er.",
"form_title": "Meld anleggsfeil",
"heading": "Meld fra om noe ødelagt",
"hints": {
"hva": "Løs planke på gjerdet ved husken",
"hvor": ""
},
"icon": "construction",
"labels": {
"hva": "Hva er ødelagt",
"hvor": "Hvor er det"
},
"road_description": "Meldingen går til lekeplasskomiteen, som ser på den og tar tak i saken. Når feilen er utbedret, er saken avsluttet.",
"road_icon": "lucide:wrench",
"road_title": "Hva skjer videre",
"who_description": "Lekeplasskomiteen leser meldingen din; til det haster kan du nå styret på post@tomtervel.no.",
"who_icon": "lucide:hammer",
"who_title": "Hvem leser dette"
},
"trafikkfare": {
"button": "Send inn",
"description": "Sett du noe farlig i trafikken? Fortell trafikkomiteen om det, så tar de det videre.",
"encouragement": "Bare noen linjer om hva og hvor er nok til at vi kan følge opp.",
"form_description": "Fortell hva du så, hvor det var, og legg gjerne igjen e-posten din hvis vi trenger å spørre mer.",
"form_title": "Meld trafikkfare",
"heading": "Meld fra om en trafikkfare",
"hints": {
"epost": "ola.nordmann@epost.no",
"hva": "Dårlig sikt i krysset, biler kjører fort",
"hvor": "Krysset Tomterveien / Elvestien"
},
"icon": "alert-triangle",
"labels": {
"epost": "E-post (valgfritt)",
"hva": "Hva så du",
"hvor": "Hvor var det"
},
"road_description": "Trafikkomiteen tar meldingen din opp med kommunen eller den som eier veien. Du får vite om saken blir ordnet eller avvist.",
"road_icon": "lucide:route",
"road_title": "Hva skjer videre",
"who_description": "Trafikkomiteen leser meldingen din; haster det, kan du nå styret på post@tomtervel.no.",
"who_icon": "lucide:car",
"who_title": "Hvem leser dette"
}
},
"question": "Hva vil du melde fra om?"
},
"questions/naboer/index.yaml": {
"description": "Godt naboskap gjør hverdagen lettere. Trenger du en hånd, kan gi en, eller har noe å låne bort?",
"needs": {
"dele-utstyr": {
"button": "Legg ut oppslag",
"description": "Har du noe naboene kan få låne, eller trenger du å låne noe selv? Legg ut et oppslag så ser de andre på Tomter det.",
"encouragement": "Vi legger det ut så naboene kan se det.",
"form_description": "Skriv kort hva det gjelder, så folk skjønner det med en gang.",
"form_title": "Lån eller utlån",
"heading": "Lån ut eller lån av naboen",
"hints": {
"email": "ola@eksempel.no",
"har_eller_trenger": "",
"hva": "Hengerfeste til bil, tilhenger, stige",
"navn": "Ola Nordmann"
},
"icon": "package",
"labels": {
"email": "E-post",
"har_eller_trenger": "Har du eller trenger du",
"hva": "Hva gjelder det",
"navn": "Navn"
},
"road_description": "Oppslaget legges ut for naboene å se. Når det er ordnet eller ikke lenger aktuelt, tas det ned igjen.",
"road_icon": "lucide:clipboard-list",
"road_title": "Fra oppslag til avtale",
"who_description": "Styret legger ut oppslaget og kan nås på post@tomtervel.no i mellomtiden.",
"who_icon": "lucide:users",
"who_title": "Hvem ser dette"
},
"kan-hjelpe": {
"button": "Meld deg",
"description": "Kan du stille opp med snømåking, en handletur eller skyss når en nabo trenger det? Meld deg, så blir du spurt når det passer.",
"encouragement": "Du blir bare kontaktet når noe passer for deg.",
"form_description": "Fortell kort hva du kan bidra med.",
"form_title": "Meld deg som hjelper",
"heading": "Bli spurt når en nabo trenger en hånd",
"hints": {
"email": "kari@eksempel.no",
"kan": "",
"navn": "Kari Nordmann",
"telefon": "123 45 678"
},
"icon": "hand-helping",
"labels": {
"email": "E-post",
"kan": "Hva kan du hjelpe med",
"navn": "Navn",
"telefon": "Telefon"
},
"road_description": "Du blir registrert som hjelper. Trekker du deg tilbake senere, er det bare å si fra.",
"road_icon": "lucide:user-check",
"road_title": "Fra påmelding til spørsmål",
"who_description": "Nabohjelpen har oversikten og ringer deg direkte når det er noe, eller nås på post@tomtervel.no.",
"who_icon": "lucide:heart-handshake",
"who_title": "Hvem ser dette"
},
"trenger-hjelp": {
"button": "Be om hjelp",
"description": "Får du ikke til snømåking, en handletur eller skyss for tiden? Si fra, så finner vi en nabo som kan stille opp.",
"encouragement": "Vi finner en nabo som kan stille opp så fort som mulig.",
"form_description": "Skriv kort hva du trenger hjelp til.",
"form_title": "Be om en hånd",
"heading": "Få en nabo til å stille opp",
"hints": {
"adresse": "Tomterveien 12",
"email": "kari@eksempel.no",
"hva": "Måke snø på trappa, handle inn litt mat",
"navn": "Kari Nordmann",
"telefon": "123 45 678"
},
"icon": "heart-handshake",
"labels": {
"adresse": "Adresse",
"email": "E-post",
"hva": "Hva trenger du hjelp til",
"navn": "Navn",
"telefon": "Telefon"
},
"road_description": "Nabohjelpen finner en nabo som kan stille opp. Er det ordnet, eller om det ikke lot seg løse, får du beskjed.",
"road_icon": "lucide:hand-helping",
"road_title": "Fra melding til hjelp",
"who_description": "Nabohjelpen tar imot og finner noen til deg, eller ring post@tomtervel.no i mellomtiden.",
"who_icon": "lucide:users",
"who_title": "Hvem ser dette"
}
},
"question": "Trenger du en hånd, eller kan du gi en?"
},
"questions/nabohjelp/index.yaml": {
"buckets": {
"hjelpebehov": {
"description": "Naboer som trenger en hånd med snømåking, handling eller skyss – klare til å bli koblet med noen som kan hjelpe.",
"heading": "Naboer som trenger en hånd",
"moves": {
"formidlet->ikke_lost": "Meld ikke løst",
"formidlet->ordnet": "Meld ordnet",
"open->formidlet": "Koble til nabo",
"open->ikke_lost": "Meld ikke løst"
}
},
"hjelpere": {
"description": "Naboer som har sagt de kan stille opp – klare til å bli spurt når noen trenger dem.",
"heading": "Naboer som kan stille opp",
"moves": {
"open->registrert": "Registrer som hjelper",
"open->trukket": "Meld trukket"
}
}
},
"confirm": "Lagre",
"description": "Her kobler du naboer som trenger hjelp med dem som kan stille opp.",
"invited": {
"description": "Hver invitasjon med lenken som ble laget. Marker som ferdig når personen er inne.",
"done": "Er inne",
"heading": "Sendte invitasjoner"
},
"invites": {
"nabohjelp": {
"button": "Inviter",
"description": "De får en konto, plass i nabohjelpen, og en engangslenke der de selv velger passord eller passnøkkel. Send lenken videre til dem.",
"form_title": "Hvem",
"heading": "Inviter noen inn i nabohjelpen",
"labels": {
"email": "E-post",
"name": "Navn"
}
}
},
"links": {},
"question": "Hvem trenger hjelp, og hvem kan stille opp?"
},
"questions/received/anleggsfeil.yaml": {
"back": "Tilbake til forsiden",
"description": "Meldingen din om skaden er sendt til lekeplasskomiteen. De ser over det du har sendt.",
"next_description": "Lekeplasskomiteen ser på meldingen og tar tak i det som må fikses før noen skader seg.",
"next_heading": "Komiteen tar tak i det",
"question": "Hva skjer med meldingen min nå?",
"see_all": {
"button": "Se meldte feil",
"description": "Se hva andre har meldt inn av skader på lekeplassene og stien, og hvor langt det har kommet.",
"heading": "Se andre meldte feil"
}
},
"questions/received/bli-medlem.yaml": {
"back": "Tilbake til forsiden",
"description": "Vi har mottatt innmeldingen din. Kasserer tar kontakt med betalingsinfo så snart medlemskapet er registrert.",
"next_description": "Kasserer går gjennom nye innmeldinger og sender deg kontonummer og beløp for kontingenten.",
"next_heading": "Kasserer sender deg betalingsinfo",
"question": "Hva skjer etter at jeg har meldt meg inn?"
},
"questions/received/dele-utstyr.yaml": {
"back": "Tilbake til forsiden",
"description": "Takk for at du la ut noe naboene kan låne. Vi legger det ut på oppslaget så snart vi kan.",
"next_description": "En i styret legger utstyret ut på naboenes oppslag, så andre kan se det og spørre om å låne.",
"next_heading": "Styret legger det ut for deg",
"question": "Hva skjer med det jeg har lagt ut?",
"see_all": {
"button": "Se hva naboer deler",
"description": "Se hva andre i Tomter har lagt ut til utlån akkurat nå.",
"heading": "Se alt naboene deler"
}
},
"questions/received/endre-medlemskap.yaml": {
"back": "Tilbake til forsiden",
"description": "Vi har mottatt beskjeden om at du har flyttet, byttet e-post eller vil melde deg ut.",
"next_description": "Kasserer oppdaterer medlemslista og gir deg beskjed hvis det er noe mer vi trenger fra deg.",
"next_heading": "Kasserer retter opp opplysningene",
"question": "Hva skjer nå med det jeg meldte inn?"
},
"questions/received/hjelpe-til.yaml": {
"back": "Tilbake til forsiden",
"description": "Takk for at du vil hjelpe til. Arrangementskomiteen har fått beskjed og tar kontakt med deg.",
"next_description": "Du hører fra noen i komiteen når de vet hva de trenger hjelp til, gjerne noen dager før arrangementet eller dugnaden.",
"next_heading": "Komiteen tar kontakt",
"question": "Hva skjer nå som jeg har meldt meg?"
},
"questions/received/horingsinnspill.yaml": {
"back": "Tilbake til forsiden",
"description": "Innspillet ditt er sendt til høringsinstansen i velet.",
"next_description": "De ser på om det kan tas med i velets høringssvar til kommunen, og gir beskjed om det blir med.",
"next_heading": "Innspillet ditt inn i vurderingen",
"question": "Hva skjer med det jeg har sagt om saken?"
},
"questions/received/kan-hjelpe.yaml": {
"back": "Tilbake til forsiden",
"description": "Takk for at du sier fra at du kan stille opp. Nabohjelp-komiteen tar imot meldingen og legger deg inn på lista over naboer som kan hjelpe.",
"next_description": "Når en nabo trenger hjelp med noe du har sagt du kan bidra med, tar komiteen kontakt med deg direkte.",
"next_heading": "Du blir kontaktet ved behov",
"question": "Hva skjer nå som jeg har registrert meg?"
},
"questions/received/komite.yaml": {
"back": "Tilbake til forsiden",
"description": "Takk for at du vil bidra! Styret har fått beskjed og ser på hvilken komité som passer best for deg.",
"next_description": "Noen fra styret tar kontakt for å høre mer om hva du liker å drive med, og finner en komité som passer.",
"next_heading": "Vi finner riktig komité til deg",
"question": "Hva skjer nå som jeg har meldt interesse for en komité?"
},
"questions/received/trafikkfare.yaml": {
"back": "Tilbake til forsiden",
"description": "Meldingen din om trafikkfaren er sendt til komiteen for trafikk.",
"next_description": "Trafikkomiteen ser gjennom meldinger jevnlig og tar det videre med kommunen eller den som eier veien der det trengs.",
"next_heading": "Trafikkomiteen tar den videre",
"question": "Hva skjer med meldingen min nå?",
"see_all": {
"button": "Se andre trafikkfarer",
"description": "Se hva andre har meldt inn, og status på sakene.",
"heading": "Andre meldte trafikkfarer"
}
},
"questions/received/trenger-hjelp.yaml": {
"back": "Til forsiden",
"description": "Meldingen din er sendt til nabohjelpa. Vi ser etter en nabo som kan stille opp.",
"next_description": "Vi tar kontakt med noen som kan hjelpe, så snart vi finner en som passer.",
"next_heading": "Vi finner en nabo til deg",
"question": "Hva skjer nå som jeg har bedt om hjelp?"
},
"questions/status/anleggsfeil/index.yaml": {
"back": "Tilbake til meldinger",
"description": "Her ser du meldinger om ødelagt lekeutstyr og skader på elvestien, og hvor langt hver sak har kommet.",
"heading": "Status på meldte anleggsfeil",
"list_description": "Alle meldinger er åpne for alle å se.",
"question": "Hva skjer med det jeg har meldt fra om?"
},
"questions/status/oppslag/index.yaml": {
"back": "Tilbake",
"description": "Her ser du alt som er sendt inn og hvor langt hvert oppslag har kommet.",
"heading": "Oversikt over det som er meldt inn",
"list_description": "Åpen liste – navn og detaljer vises ikke.",
"question": "Hva er sendt inn, og hvor langt har det kommet?"
},
"questions/status/trafikkmeldinger/index.yaml": {
"back": "Tilbake",
"description": "Her ser du farlige steder i trafikken som er meldt inn, og hvor langt saken har kommet.",
"heading": "Trafikkmeldinger og status",
"list_description": "Alle meldinger som er sendt inn, og hvor de står nå.",
"question": "Er det meldt fra om noe farlig i trafikken der jeg bor?"
},
"questions/styret/index.yaml": {
"buckets": {
"innspill": {
"description": "Her samles meninger fra beboerne om saker kommunen har på høring, klare til å tas med i velets svar.",
"heading": "Høringsinnspill fra beboerne",
"moves": {}
},
"komitesoknader": {
"description": "Her ligger alle som har meldt seg til en komité og venter på en plass.",
"heading": "Søknader til komiteene",
"moves": {
"open->avslatt": "Avslå søknaden",
"open->plassert": "Sett i komité"
}
},
"oppslag": {
"description": "Her ligger det naboer har å låne ut eller trenger å låne, klart til å legges ut.",
"heading": "Utstyr til utlån blant naboer",
"moves": {
"open->lagt_ut": "Legg ut oppslaget",
"open->tatt_ned": "Ta ned oppslaget"
}
},
"trafikkmeldinger": {
"description": "Her samles meldinger om farlige steder i trafikken, klare til å tas videre med kommunen eller veieier.",
"heading": "Meldinger om trafikkfarer",
"moves": {}
}
},
"confirm": "Lagre",
"description": "Herfra følger styret opp det som ikke hører under en enkelt komité: høringssvar, komitéplasser og oppslag fra naboer.",
"invited": {
"description": "Hver invitasjon med lenken som ble laget. Marker som ferdig når personen er inne.",
"done": "Er inne",
"heading": "Sendte invitasjoner"
},
"invites": {
"arrangementer": {
"button": "Inviter",
"description": "De får en konto, plass i Arrangementer, og en engangslenke der de selv velger passord eller passnøkkel. Send lenken videre til dem.",
"form_title": "Hvem",
"heading": "Inviter noen inn i Arrangementer",
"labels": {
"email": "E-post",
"name": "Navn"
}
},
"horingsinstans": {
"button": "Inviter",
"description": "De får en konto, plass i Høringsinstans, og en engangslenke der de selv velger passord eller passnøkkel. Send lenken videre til dem.",
"form_title": "Hvem",
"heading": "Inviter noen inn i Høringsinstans",
"labels": {
"email": "E-post",
"name": "Navn"
}
},
"kasserer": {
"button": "Inviter",
"description": "De får en konto, plass i kassereren, og en engangslenke der de selv velger passord eller passnøkkel. Send lenken videre til dem.",
"form_title": "Hvem",
"heading": "Inviter noen inn i kassereren",
"labels": {
"email": "E-post",
"name": "Navn"
}
},
"komiteer": {
"button": "Inviter",
"description": "De får en konto, plass i komiteene, og en engangslenke der de selv velger passord eller passnøkkel. Send lenken videre til dem.",
"form_title": "Hvem",
"heading": "Inviter noen inn i komiteene",
"labels": {
"email": "E-post",
"name": "Navn"
}
},
"lekeplasser": {
"button": "Inviter",
"description": "De får en konto, plass i Leke- og møteplasser, og en engangslenke der de selv velger passord eller passnøkkel. Send lenken videre til dem.",
"form_title": "Hvem",
"heading": "Inviter noen inn i Leke- og møteplasser",
"labels": {
"email": "E-post",
"name": "Navn"
}
},
"nabohjelp": {
"button": "Inviter",
"description": "De får en konto, plass i nabohjelpen, og en engangslenke der de selv velger passord eller passnøkkel. Send lenken videre til dem.",
"form_title": "Hvem",
"heading": "Inviter noen inn i nabohjelpen",
"labels": {
"email": "E-post",
"name": "Navn"
}
},
"styret": {
"button": "Inviter",
"description": "De får en konto, plass i styret, og en engangslenke der de selv velger passord eller passnøkkel. Send lenken videre til dem.",
"form_title": "Hvem",
"heading": "Inviter noen inn i styret",
"labels": {
"email": "E-post",
"name": "Navn"
}
},
"trafikk": {
"button": "Inviter",
"description": "De får en konto, plass i Trafikkforhold, og en engangslenke der de selv velger passord eller passnøkkel. Send lenken videre til dem.",
"form_title": "Hvem",
"heading": "Inviter noen inn i Trafikkforhold",
"labels": {
"email": "E-post",
"name": "Navn"
}
}
},
"links": {},
"question": "Hva venter på styret akkurat nå?"
},
"questions/trafikk/index.yaml": {
"buckets": {
"trafikkmeldinger": {
"description": "Farlige steder i trafikken som naboer har meldt inn.",
"heading": "Farlige steder i trafikken",
"moves": {
"open->avvist": "Avvis meldingen",
"open->tatt_opp": "Ta opp med kommunen",
"tatt_opp->avvist": "Avvis meldingen",
"tatt_opp->ordnet": "Meld ordnet"
}
}
},
"confirm": "Lagre",
"description": "Her ser du meldinger om farlige steder i trafikken og følger dem opp overfor kommunen eller veieier.",
"invited": {
"description": "Hver invitasjon med lenken som ble laget. Marker som ferdig når personen er inne.",
"done": "Er inne",
"heading": "Sendte invitasjoner"
},
"invites": {
"trafikk": {
"button": "Inviter",
"description": "De får en konto, plass i Trafikkforhold, og en engangslenke der de selv velger passord eller passnøkkel. Send lenken videre til dem.",
"form_title": "Hvem",
"heading": "Inviter noen inn i Trafikkforhold",
"labels": {
"email": "E-post",
"name": "Navn"
}
}
},
"links": {},
"question": "Hvilke trafikkfarer må følges opp?"
}
}
+57 -2
View File
@@ -934,6 +934,43 @@ pub fn merge_words(fallback: &Value, given: &Value) -> Value {
const SLOT: &str = "<WRITE"; const SLOT: &str = "<WRITE";
/// A model asked for Norwegian sometimes answers in English, and the
/// reverse; the words then look fine and read wrong. Counts the
/// commonest function words of each language across every string of
/// a reply and names the language that won when it is not the plan's.
/// Only the two languages the plans come in; any other language is
/// left unchecked.
fn wrong_language(lang: &str, reply: &Value) -> Option<&'static str> {
const NORWEGIAN: &[&str] = &["og", "er", "du", "det", "ikke", "til", "som", "med", "på", "har", "vi", "deg", "en", "et"];
const ENGLISH: &[&str] = &["the", "and", "you", "is", "are", "we", "to", "of", "your", "it", "in", "with", "for", "a"];
fn collect(v: &Value, out: &mut String) {
match v {
Value::String(s) => {
out.push(' ');
out.push_str(s);
}
Value::Object(m) => m.values().for_each(|v| collect(v, out)),
Value::Array(a) => a.iter().for_each(|v| collect(v, out)),
_ => {}
}
}
let mut text = String::new();
collect(reply, &mut text);
let words: Vec<String> = text.split(|c: char| !c.is_alphabetic()).filter(|w| !w.is_empty()).map(|w| w.to_lowercase()).collect();
if words.len() < 8 {
return None;
}
let no = words.iter().filter(|w| NORWEGIAN.contains(&w.as_str())).count();
let en = words.iter().filter(|w| ENGLISH.contains(&w.as_str())).count();
let plan_is_norwegian = lang.starts_with("no") || lang.starts_with("nb") || lang.starts_with("nn");
let plan_is_english = lang.starts_with("en");
match (plan_is_norwegian, plan_is_english) {
(true, _) if en > no * 2 && en >= 4 => Some("English"),
(_, true) if no > en * 2 && no >= 4 => Some("Norwegian"),
_ => None,
}
}
/// A mail's link to the submitter's own move is structure, not /// A mail's link to the submitter's own move is structure, not
/// wording: a model told to keep it still drops it (Sonnet replaced /// wording: a model told to keep it still drops it (Sonnet replaced
/// the whole line with a bare `{chain}`). Wherever the fallback body /// the whole line with a bare `{chain}`). Wherever the fallback body
@@ -1514,8 +1551,13 @@ pub fn run(argv: &[String]) -> anyhow::Result<()> {
if path == "aggregates.yaml" { if path == "aggregates.yaml" {
keep_links(fallback, &mut merged); keep_links(fallback, &mut merged);
} }
words.insert(path.clone(), merged); match wrong_language(&plan.language, &given) {
eprintln!("words: {path}"); Some(found) => eprintln!("words: {path} - the reply reads as {found} for a {} plan, keeping the words it had", plan.language),
None => {
words.insert(path.clone(), merged);
eprintln!("words: {path}");
}
}
} }
None => eprintln!("words: {path} - no usable reply, keeping the fallback"), None => eprintln!("words: {path} - no usable reply, keeping the fallback"),
} }
@@ -1592,6 +1634,19 @@ mod tests {
assert!(serde_yaml::from_str::<Plan>(&no_from).unwrap().validate().unwrap_err().to_string().contains("mail: { from")); assert!(serde_yaml::from_str::<Plan>(&no_from).unwrap().validate().unwrap_err().to_string().contains("mail: { from"));
} }
#[test]
fn a_reply_in_the_wrong_language_is_named() {
let english = json!({ "a": { "body": "We have received what you sent and we will read it in full before we reply to you." } });
let norwegian = json!({ "a": { "body": "Vi har mottatt det du sendte og leser det i sin helhet før vi svarer deg på det." } });
assert_eq!(wrong_language("no", &english), Some("English"));
assert_eq!(wrong_language("no", &norwegian), None);
assert_eq!(wrong_language("en", &norwegian), Some("Norwegian"));
assert_eq!(wrong_language("en", &english), None);
// Too short to tell, or a language nobody checks: left alone.
assert_eq!(wrong_language("no", &json!({ "a": "Send" })), None);
assert_eq!(wrong_language("de", &english), None);
}
#[test] #[test]
fn a_models_mail_keeps_the_submitters_link() { fn a_models_mail_keeps_the_submitters_link() {
let fallback = json!({ "leaks": { "open": { "subject": "s", "body": "Hello,\n\nGot it.\n\nWhat you can do next: {site}/decide/leak?chain={chain}&email={email}\n\nI at i@b.example" } } }); let fallback = json!({ "leaks": { "open": { "subject": "s", "body": "Hello,\n\nGot it.\n\nWhat you can do next: {site}/decide/leak?chain={chain}&email={email}\n\nI at i@b.example" } } });