diff --git a/README.md b/README.md index 066a21e..8e884e0 100644 --- a/README.md +++ b/README.md @@ -178,6 +178,21 @@ the business's own words and held-out personas. applicant is declined before they start and departs after, which is what uhhm.no's live machine says and what two near-synonymous desk buttons had been standing in for. +- `reached_from: { : [, ...] }` on a need: where a stage + is entered from, when the line a case walks does not say it. Two + shapes need it and nothing else does - a case SENT BACK to a stage it + was already past (a building application returned for the drawing it + was missing, after the hearing turned something up), and a GOOD ENDING + PARTWAY ALONG (an authority that changes its own decision while it is + looking at the appeal, rather than passing it up to the board). A + stage named there is entered from exactly those stages and nowhere + else, so saying where a refusal may come from also says where it may + not: an applicant may withdraw from anywhere, and be refused only once + the papers are in, which `turned_down_from` could not express because + it was one list for every bad ending at once. Found by replaying a + building authority's real cases through portal's engine, which + refused three legal paths and accepted two illegal ones until the + plan could say this; see runs/permits-2026-09-25/README.md. - `attended_by:` on a need: who moves cases that no desk button moves, an automation listening on the bucket's events, written into aggregates.yaml as portal's own annotation for the reader. diff --git a/intakes/building-permits-personas.yaml b/intakes/building-permits-personas.yaml new file mode 100644 index 0000000..c2425d5 --- /dev/null +++ b/intakes/building-permits-personas.yaml @@ -0,0 +1,28 @@ +# Held out from every model that writes words. Each is one real person +# arriving with one real thing, in their own register: a homeowner who +# has never read a regulation, a firm that files for a living, an +# inspector on a roof in the wind, a politician reading a bundle. +personas: + - { id: garage-owner, need: pre-application-meeting, text: "We want to put a double garage where the old shed is. Before I pay an architect I'd like to know whether you'll even allow it, because the neighbour says it's too close to the road." } + - { id: shop-to-flats, need: pre-application-meeting, text: "I own the old grocery on Torget and want to make four flats out of it. There are a lot of questions - parking, fire, the facade is listed. Can we sit down with someone?" } + - { id: firm-files-extension, need: permit-application, text: "We are the responsible applicant for an extension at Bjorkeveien 14. Drawings, site plan and the neighbour notices are all ready. We file maybe forty of these a year." } + - { id: owner-small-window, need: permit-application, text: "I want to put a dormer window in my roof. The man at the counter said I have to apply even though it's small." } + - { id: missing-drawings, need: permit-application, text: "You wrote that our section drawing is missing and the case is on hold. I've got it here now, where do I send it so the clock starts again?" } + - { id: too-close-to-boundary, need: exemption-request, text: "The garage ends up one and a half metres from the boundary and the plan says four. We are asking you to allow it anyway - the ground falls away steeply everywhere else on the plot." } + - { id: neighbour-view, need: objection, text: "I got a notice about the extension at number 14. It takes the afternoon sun off my entire terrace and I want that on the record before you decide anything." } + - { id: neighbour-parking, need: objection, text: "The flats they want to build in the old grocery have four parking places for four flats and everyone here already parks on the street. I object." } + - { id: road-authority, need: hearing-answer, text: "Regarding your case 2026/418: the access onto the county road is within the sight line and we cannot accept it as drawn. Our formal reply is attached." } + - { id: fire-service, need: hearing-answer, text: "We have looked at the conversion on Torget. We have no objection provided the stairwell is upgraded. Reference your case 2026/501." } + - { id: refused-applicant, need: appeal, text: "You refused our exemption on the ninth. We don't accept the reasoning - you've allowed the same thing twice in the same street. We're appealing." } + - { id: neighbour-appeals, need: appeal, text: "You approved the extension next door even though I objected. I'm appealing the decision. What do I need to send?" } + - { id: board-member, need: appeal, text: "I sit on the appeals board. I need the case, our own decision, and what the neighbours wrote, before Tuesday." } + - { id: inspector-on-roof, need: inspection-finding, text: "I'm up on the scaffold at Bjorkeveien. The fire wall isn't built to the drawing at all. I've got gloves on and it's blowing. I want this logged before I climb down." } + - { id: inspector-all-good, need: inspection-finding, text: "Been out at Torget. Everything is as approved. Nothing to report but I have to record that I was there." } + - { id: firm-wants-certificate, need: completion-request, text: "The work at Bjorkeveien 14 is finished and inspected. We're asking for the completion certificate so the owners can get their mortgage released." } + - { id: wants-to-move-in, need: completion-request, text: "The house is done apart from the outside steps, which we can't pour until spring. The family has sold their flat. Can we get a temporary permission to move in?" } + - { id: something-behind-fence, need: illegal-building-report, text: "There's a large structure going up behind the fence at Solbakken 7. Nobody has had a notice about it and it's been going on for two weeks." } + - { id: owner-explains, need: illegal-building-report, text: "I got your letter about the terrace. I genuinely did not know it needed an application, it's been there since we moved in. What happens now?" } + - { id: new-firm, need: firm-approval, text: "We are a three-person architecture firm that has just started. We want to be approved so we can file applications for our clients in your municipality." } + - { id: firm-insurance-lapsed, need: firm-approval, text: "You wrote that our liability insurance certificate has expired. We have renewed it, here it is." } + - { id: counter-phone-call, need: log-counter-enquiry, text: "A woman rang about the case behind her house. Wants to know where it stands. I'm at the counter and there's a queue - I need to write it down and send it to whoever has that case." } + - { id: where-is-my-case, need: case-status-enquiry, text: "I sent in my application five weeks ago and I've heard nothing. Is anyone looking at it? Is it in the six weeks with the neighbours or is it waiting on me?" } diff --git a/intakes/building-permits.yaml b/intakes/building-permits.yaml new file mode 100644 index 0000000..9de3825 --- /dev/null +++ b/intakes/building-permits.yaml @@ -0,0 +1,91 @@ +# A building authority's intake: the hardest sector the trainer has +# been given. Cases that pause and resume, cases that belong to other +# cases, a decision two roles sign, a deadline nobody in the building +# controls, and an appeal that reopens something already finished. +# Written the way the department head would write it, in plain words. +business: Vestmark kommune - Building and Planning +contact: { name: Solveig Hauge, email: byggesak@vestmark.example } +language: en + +what_we_do: > + We are the building authority for a municipality of twenty-one + thousand people. Anyone who wants to build, demolish, divide a + property or change what a building is used for has to come to us + first. We check the drawings against the zoning map and the building + regulations, we let the neighbours and the other authorities have + their say, and then we approve or refuse. We also decide exemptions + from the zoning rules, we inspect what is actually built, we sign off + finished work, and we deal with building that was never applied for. + +who_comes_to_us: > + Homeowners who want a garage, an extension or a new window, and who + have never read a regulation in their life. Architects and + engineering firms who file on behalf of owners; they have to be + approved by us before they may file anything. Neighbours who got a + notice in the post and do not agree with what is planned next door. + The other authorities we are obliged to ask: the road authority, the + fire service, the heritage office, the county. People who ring to say + something is going up behind their fence without permission. And + anyone who wants to sit down with us before they spend eighty + thousand on drawings. + +what_we_keep_track_of: > + Pre-application meetings: someone asks for one, we find a time, we + meet, and we write down what we told them so they can hold us to it. + Applications: they arrive, someone checks whether the papers are all + there, and if something is missing we write and ask for it, and the + twelve-week clock stops until they answer. Often we have to ask + twice. When it is complete we send it out to the neighbours and to + the agencies and wait six weeks. Then a case officer writes a + recommendation, and the head of section signs the decision: approved, + approved with conditions, or refused. People can withdraw at any + point, and quite a few do once they hear from the neighbours. + Exemptions: if what someone wants breaks the zoning rules they can + ask for an exemption. It rides along with the application but it is a + decision of its own, and we are not allowed to grant one before the + county has been asked. + Objections: a neighbour who got a notice writes to us within the + hearing period. Each objection belongs to an application. We register + it, the applicant gets to answer it, and the case officer has to + address every single one in the decision, by name. + Hearing answers: we ask an agency, they answer, or they do not, and + when the deadline has passed we go on without them. + Appeals: for three weeks after a decision anyone with an interest can + appeal it. We go through it ourselves first, and if we change our own + mind that is the end of it. If we do not, it goes to the appeals + board, who meet once a month and either uphold us or overturn us. + Inspections: we pick cases and go and look, on site. Either it is as + approved, or we write up what is wrong and set a date for it to be + put right, and then we go back. + Finishing: when the work is done the firm asks for a completion + certificate. If they want to move in before everything is done they + can ask for a temporary permission instead. We check what was + inspected and what is still outstanding before we sign anything. + Illegal building: someone reports it, we go and look, we write to the + owner and they have to explain themselves, and then they either apply + for it properly, take it down, or we fine them weekly until they do. + Approved firms: a firm sends us their registration, their insurance + and what they are qualified for, we check it, and then they are on + the list and may file applications. + +who_is_involved: > + The front desk logs what comes in over the counter and on the phone, + and keeps the archive. Four case officers carry the cases. The head + of section signs every decision and every exemption; a case officer + may not sign their own. Two inspectors are out on site most of the + week and write up what they find on a phone in a cold wind. The + appeals board is seven elected politicians who meet on the third + Tuesday of the month and read what we send them. The agencies are + outside the building altogether and only ever answer hearings. The + approved firms file applications and answer objections on behalf of + their clients. + +what_slows_us_down: > + The twelve-week clock, and the fact that stopping it and starting it + again is done by hand in a spreadsheet. Applications that arrive + missing half the drawings. Objections that come in on paper and get + stapled to the wrong case. Neighbours ringing to ask what is + happening with the case behind their house, which we are obliged to + tell them and which takes ten minutes every time. Agencies that never + answer at all. And nobody outside this building can see a case + without asking us for it. diff --git a/plans/building-permits.yaml b/plans/building-permits.yaml new file mode 100644 index 0000000..5ecfb5e --- /dev/null +++ b/plans/building-permits.yaml @@ -0,0 +1,487 @@ +# A building authority, written by hand to find where the plan language +# stops. 14 needs, 7 roles, 12 buckets, two needs sharing a bucket in +# each direction (public and internal), a decision no case officer may +# sign, a group outside the building that moves records and nothing +# else, a stage a deadline moves rather than a person, and four things +# the plan language cannot say at all - each named in the run's README +# rather than smuggled past. +business: Vestmark kommune - Building and Planning +language: en +contact: { name: Solveig Hauge, email: byggesak@vestmark.example } +mail: { from: "Vestmark Building and Planning ", reply_to: byggesak@vestmark.example } +about: > + The building authority for twenty-one thousand people. Anything built, + demolished, divided or changed in use is decided here: the drawings are + checked against the zoning map, the neighbours and the other + authorities have their say, and then the head of section signs. The + same office inspects what is actually built, signs off finished work, + and deals with building nobody applied for. + +# Two features, two roles, no button. The authority exists for the +# person who wants to build; the next one it serves is the neighbour +# who finds out what is planned next door. Both have a move of their +# own after sending: the applicant withdraws, the objector withdraws, +# and both buckets are open to read. +does: + - id: we-decide-what-may-be-built + for: small-works-application + text: > + Everything built in Vestmark is decided here. You send the drawings, + the neighbours and the road, fire and heritage authorities are heard, + and you get a written decision you can hold us to. + - id: your-neighbours-case-is-readable + for: objection + text: > + If a notice landed in your postbox, the case behind it is open to + read here, and what you write to us has to be answered by name in + the decision. + +doors: + - id: want-to-build + who: an owner or a firm with something to build, divide or change + - id: building-near-me + who: someone who lives next to what is being built + +groups: + - { id: front_desk, label: Front desk } + - { id: case_officers, label: Case officers } + - { id: section_head, label: Head of section } + - { id: inspectors, label: Inspectors } + - { id: appeals_board, label: Appeals board, invited_by: [section_head] } + - { id: agencies, label: Hearing bodies, invited_by: [case_officers, section_head] } + - { id: approved_firms, label: Approved firms, invited_by: [section_head] } +invites_by: [section_head, case_officers] + +needs: + # --- the public: something they want to build ---------------------- + - id: pre-application-meeting + door: want-to-build + who: someone with an idea for a building and no drawings yet + wants: to hear what we will allow before paying an architect + lands_in: meetings + handled_by: case_officers + stages: [open, scheduled, met, advised, cancelled] + done_when: [advised, cancelled] + success: [advised] + # They can call it off themselves; the front desk does it when they ring. + moves_by: { cancelled: [submitter, front_desk] } + watched_by: [front_desk] + mails: { open: submitter, scheduled: submitter, advised: submitter } + stages_text: { met: we have met, advised: written advice sent } + max_fields: 5 + collects: + - { name: name } + - { name: email, type: email } + - { name: property_address } + - { name: what_you_want, type: textarea } + - { name: phone, type: tel, optional: true } + - { name: site, type: location, optional: true } + + - id: small-works-application + door: want-to-build + who: an owner applying for something small enough to file themselves + wants: permission to build it, and to know where the case stands + lands_in: applications + handled_by: case_officers + stages: [open, incomplete, complete, on_hearing, recommended, approved, approved_with_conditions, refused, withdrawn] + done_when: [approved, approved_with_conditions, refused, withdrawn] + success: [approved, approved_with_conditions] + skippable: [incomplete] + # A case is sent back for the drawing it was missing, and the + # hearing turns things up that send it back again. It may be + # withdrawn from anywhere, and refused only once we have seen + # everything: not on the day it arrives. + reached_from: + incomplete: [open, complete, on_hearing] + refused: [complete, on_hearing, recommended] + # No case officer signs their own case: only the head of section + # moves one into a decision. The applicant answers a request for + # missing papers, and may withdraw right up to the signature. + moves_by: + complete: [submitter, case_officers] + approved: [section_head] + approved_with_conditions: [section_head] + refused: [section_head] + withdrawn: [submitter] + watched_by: [public, front_desk, inspectors, section_head] + mails: + open: submitter + incomplete: submitter + on_hearing: submitter + approved: submitter + approved_with_conditions: submitter + refused: submitter + stages_text: + incomplete: papers missing + complete: papers complete + on_hearing: out to the neighbours and the agencies + recommended: recommendation written + approved_with_conditions: approved on conditions + max_fields: 6 + collects: + - { name: email, type: email } + - { name: property_address } + - { name: property_number } + - { name: what_is_planned, type: textarea } + - { name: neighbours_notified, type: select, options: ["Yes", Not yet] } + - { name: site, type: location, optional: true } + - { name: drawings_url, optional: true } + + - id: exemption-request + door: want-to-build + who: someone whose plans break a rule in the zoning map + wants: to be allowed it anyway, with reasons on the record + requires: An application already with us, and the case number from its receipt. + lands_in: exemptions + handled_by: case_officers + stages: [open, county_asked, county_answered, recommended, granted, denied, withdrawn] + done_when: [granted, denied, withdrawn] + success: [granted] + # The county answers from outside the building; nothing may be + # granted before it has. The head of section signs, as for a permit. + moves_by: + county_answered: [agencies] + granted: [section_head] + denied: [section_head] + withdrawn: [submitter] + watched_by: [public, section_head] + mails: { open: submitter, county_asked: submitter, granted: submitter, denied: submitter } + stages_text: { county_asked: with the county, county_answered: the county has answered } + max_fields: 4 + collects: + - { name: email, type: email } + - { name: case_number } + - { name: which_rule } + - { name: why_it_should_be_allowed, type: textarea } + - { name: site, type: location, optional: true } + + - id: completion-request + door: want-to-build + who: an owner or firm whose building work is finished + wants: the certificate that lets the building be used + requires: A case number, and the work finished or close enough to move in. + lands_in: completions + handled_by: case_officers + stages: [open, checked, temporary_permission, certificate_issued, refused] + done_when: [certificate_issued, refused] + success: [certificate_issued] + # Most go straight through; the ones who want to move in before the + # last of it is done detour past a temporary permission. + skippable: [temporary_permission] + moves_by: + temporary_permission: [section_head] + certificate_issued: [section_head] + refused: [section_head] + watched_by: [public, inspectors] + turned_down_from: [open, checked] + mails: { open: submitter, temporary_permission: submitter, certificate_issued: submitter, refused: submitter } + stages_text: { checked: checked against the inspections, temporary_permission: temporary permission to use, certificate_issued: certificate issued } + max_fields: 5 + collects: + - { name: email, type: email } + - { name: case_number } + - { name: property_address } + - { name: work_finished, type: date } + - { name: asking_for, type: select, options: [Completion certificate, Temporary permission to move in] } + - { name: what_is_outstanding, type: textarea, optional: true } + + # --- the public: someone else is building --------------------------- + - id: objection + door: building-near-me + who: a neighbour who got a notice about what is planned next door + wants: what they think on the record, and answered in the decision + requires: The notice that came in the post, which has the case number on it. + lands_in: objections + handled_by: case_officers + stages: [open, registered, answered_by_applicant, addressed, withdrawn] + done_when: [addressed, withdrawn] + success: [addressed] + # The firm that filed the case answers the objection; the neighbour + # can take it back if they are satisfied. + moves_by: { answered_by_applicant: [approved_firms, case_officers], withdrawn: [submitter] } + watched_by: [public, section_head] + mails: { open: submitter, answered_by_applicant: submitter, addressed: submitter } + stages_text: { registered: on the case file, answered_by_applicant: the applicant has answered, addressed: answered in the decision } + max_fields: 4 + collects: + - { name: email, type: email } + - { name: case_number } + - { name: your_property } + - { name: your_objection, type: textarea } + + - id: case-status-enquiry + door: building-near-me + who: someone waiting on a case and getting nothing back + wants: to be told where it actually stands + lands_in: enquiries + handled_by: front_desk + stages: [open, in_hand, answered] + done_when: [answered] + success: [answered] + moves_by: { in_hand: [front_desk, case_officers] } + watched_by: [case_officers] + mails: { open: submitter, answered: submitter } + max_fields: 3 + collects: + - { name: email, type: email } + - { name: case_number_or_address } + - { name: what_you_want_to_know, type: textarea } + + - id: illegal-building-report + door: building-near-me + who: someone who can see building going up that nobody was told about + wants: us to go and look, and to hear that we did + lands_in: illegal_building + handled_by: inspectors + stages: [open, inspected, owner_asked, explained, resolved, fined, dropped] + done_when: [resolved, fined, dropped] + success: [resolved, dropped] + # An inspector goes and looks; the letter to the owner is a case + # officer's, and so is the fine. + moves_by: { owner_asked: [case_officers], explained: [case_officers], fined: [section_head] } + watched_by: [case_officers, section_head] + turned_down_from: [open, inspected] + mails: { open: submitter, inspected: submitter, resolved: submitter, dropped: submitter } + stages_text: { owner_asked: the owner has been written to, explained: the owner has answered, dropped: nothing to pursue } + max_fields: 3 + collects: + - { name: email, type: email } + - { name: address } + - { name: what_you_saw, type: textarea } + - { name: where, type: location, optional: true } + + # --- the public: after a decision ------------------------------------ + - id: appeal + who: anyone with an interest who will not accept a decision of ours + wants: the decision looked at again, by us and then by the board + requires: A decision from us less than three weeks old, and its case number. + lands_in: appeals + handled_by: case_officers + stages: [open, reconsidered, changed_by_us, before_the_board, upheld, overturned, withdrawn] + done_when: [changed_by_us, upheld, overturned, withdrawn] + success: [changed_by_us, upheld] + # If we change our own mind that is the end of it, and it happens + # while we are looking - not after the board has the case. The + # board can only decide what has reached it. + reached_from: + changed_by_us: [reconsidered] + upheld: [before_the_board] + overturned: [before_the_board] + # We look at ourselves first and the head of section decides whether + # we were wrong. What we will not change goes to seven elected + # people who meet once a month and move nothing else in this office. + moves_by: + changed_by_us: [section_head] + before_the_board: [section_head] + upheld: [appeals_board] + overturned: [appeals_board] + withdrawn: [submitter] + watched_by: [public, front_desk, section_head] + mails: + open: submitter + reconsidered: submitter + changed_by_us: submitter + before_the_board: submitter + upheld: submitter + overturned: submitter + stages_text: + reconsidered: we are looking at it again + changed_by_us: we changed our own decision + before_the_board: with the appeals board + upheld: the board kept our decision + overturned: the board overturned us + max_fields: 5 + collects: + - { name: email, type: email } + - { name: case_number } + - { name: property } + - { name: what_you_disagree_with, type: textarea } + - { name: your_interest, type: select, options: [I applied, I am a neighbour, Other] } + + # --- the public: a firm that wants to file here ----------------------- + - id: firm-approval + who: an architect or engineering firm that files for its clients + wants: to be on the list, and then to file without asking again + lands_in: firms + handled_by: case_officers + stages: [open, papers_missing, checked, approved, declined] + done_when: [approved, declined] + success: [approved] + skippable: [papers_missing] + moves_by: { checked: [submitter, case_officers], approved: [section_head], declined: [section_head] } + watched_by: [section_head, front_desk] + turned_down_from: [open, papers_missing, checked] + mails: { open: submitter, papers_missing: submitter, approved: submitter, declined: submitter } + stages_text: { papers_missing: waiting on papers, checked: papers checked } + max_fields: 6 + collects: + - { name: firm_name } + - { name: org_number } + - { name: email, type: email } + - { name: qualified_for, type: select, multiple: true, options: [Design, Execution, Independent control, Site management] } + - { name: insurance_expires, type: date } + - { name: insurance_document, optional: true } + + # --- approved firms ---------------------------------------------------- + - id: permit-application + who: an approved firm filing on behalf of an owner + wants: a decision inside twelve weeks, and to know when the clock stops + enters_as: approved_firms + lands_in: applications + handled_by: case_officers + stages: [open, incomplete, complete, on_hearing, recommended, approved, approved_with_conditions, refused, withdrawn] + done_when: [approved, approved_with_conditions, refused, withdrawn] + success: [approved, approved_with_conditions] + skippable: [incomplete] + # A case is sent back for the drawing it was missing, and the + # hearing turns things up that send it back again. It may be + # withdrawn from anywhere, and refused only once we have seen + # everything: not on the day it arrives. + reached_from: + incomplete: [open, complete, on_hearing] + refused: [complete, on_hearing, recommended] + moves_by: + complete: [submitter, case_officers] + approved: [section_head] + approved_with_conditions: [section_head] + refused: [section_head] + withdrawn: [submitter] + watched_by: [public, front_desk, inspectors, section_head] + mails: + open: submitter + incomplete: submitter + on_hearing: submitter + approved: submitter + approved_with_conditions: submitter + refused: submitter + stages_text: + incomplete: papers missing + complete: papers complete + on_hearing: out to the neighbours and the agencies + recommended: recommendation written + approved_with_conditions: approved on conditions + max_fields: 6 + collects: + - { name: email, type: email } + - { name: property_address } + - { name: property_number } + - { name: what_is_planned, type: textarea } + - { name: neighbours_notified, type: select, options: ["Yes", Not yet] } + - { name: site, type: location, optional: true } + - { name: drawings_url, optional: true } + + # --- the front desk ----------------------------------------------------- + - id: log-counter-enquiry + who: whoever is on the counter with a queue and a caller on the line + wants: the question written down and sent to whoever has the case + enters_as: front_desk + lands_in: enquiries + handled_by: front_desk + stages: [open, in_hand, answered] + done_when: [answered] + success: [answered] + moves_by: { in_hand: [front_desk, case_officers] } + watched_by: [case_officers] + mails: { open: submitter, answered: submitter } + max_fields: 3 + collects: + - { name: email, type: email } + - { name: case_number_or_address } + - { name: what_you_want_to_know, type: textarea } + + # --- case officers ------------------------------------------------------ + - id: request-hearing + who: a case officer sending a case out to the authority that must see it + wants: an answer by the deadline, or a record that none came + enters_as: case_officers + lands_in: hearings + handled_by: case_officers + stages: [open, answered, no_answer, cancelled] + done_when: [answered, no_answer, cancelled] + success: [answered] + # This is how an agency sees what it has been asked. Nobody presses + # a button for the deadline passing. + moves_by: { answered: [agencies] } + watched_by: [agencies, section_head, front_desk] + attended_by: > + the six-week deadline: when it passes with nothing from the agency + the case goes to no_answer and the application goes on without one + stages_text: { no_answer: the deadline passed with no answer } + max_fields: 4 + collects: + - { name: case_number } + - { name: which_authority, type: select, options: [Road authority, Fire service, Heritage office, The county] } + - { name: what_we_ask, type: textarea } + - { name: answer_by, type: date } + - { name: site, type: location, optional: true } + + # --- the authorities outside the building -------------------------------- + - id: hearing-answer + who: a road, fire, heritage or county officer who has been asked about a case + wants: their answer on the file, in their own words + requires: The hearing letter we sent you, which has the case number on it. + enters_as: agencies + lands_in: hearing_answers + handled_by: case_officers + stages: [open, read, followed, set_aside] + done_when: [followed, set_aside] + success: [followed] + watched_by: [section_head, front_desk] + stages_text: { read: read by the case officer, followed: followed in the decision, set_aside: set aside with reasons } + max_fields: 4 + collects: + - { name: case_number } + - { name: which_authority, type: select, options: [Road authority, Fire service, Heritage office, The county] } + - { name: our_answer, type: select, options: [No objection, Objection, Conditions required] } + - { name: what_we_say, type: textarea } + + # --- inspectors ----------------------------------------------------------- + - id: inspection-finding + who: an inspector on a scaffold with gloves on and the wind blowing + wants: what they found logged before they climb down + enters_as: inspectors + lands_in: inspections + handled_by: inspectors + stages: [open, as_approved, deviation, put_right, escalated] + done_when: [as_approved, put_right, escalated] + success: [as_approved, put_right] + # Anything that has to become a fine or a refusal leaves the + # inspectors and becomes a case officer's problem. + moves_by: { escalated: [case_officers, section_head] } + watched_by: [case_officers, section_head] + stages_text: { as_approved: built as approved, deviation: built differently, put_right: put right, escalated: handed to a case officer } + max_fields: 3 + collects: + - { name: case_number } + - { name: site_address } + - { name: what_i_found, type: textarea } + - { name: where, type: location, optional: true } + +# Held out from every model that writes words. +# arriving with one real thing, in their own register: a homeowner who +# has never read a regulation, a firm that files for a living, an +# inspector on a roof in the wind, a politician reading a bundle. +personas: + - { id: garage-owner, need: pre-application-meeting, text: "We want to put a double garage where the old shed is. Before I pay an architect I'd like to know whether you'll even allow it, because the neighbour says it's too close to the road." } + - { id: shop-to-flats, need: pre-application-meeting, text: "I own the old grocery on Torget and want to make four flats out of it. There are a lot of questions - parking, fire, the facade is listed. Can we sit down with someone?" } + - { id: firm-files-extension, need: permit-application, text: "We are the responsible applicant for an extension at Bjorkeveien 14. Drawings, site plan and the neighbour notices are all ready. We file maybe forty of these a year." } + - { id: owner-small-window, need: permit-application, text: "I want to put a dormer window in my roof. The man at the counter said I have to apply even though it's small." } + - { id: missing-drawings, need: permit-application, text: "You wrote that our section drawing is missing and the case is on hold. I've got it here now, where do I send it so the clock starts again?" } + - { id: too-close-to-boundary, need: exemption-request, text: "The garage ends up one and a half metres from the boundary and the plan says four. We are asking you to allow it anyway - the ground falls away steeply everywhere else on the plot." } + - { id: neighbour-view, need: objection, text: "I got a notice about the extension at number 14. It takes the afternoon sun off my entire terrace and I want that on the record before you decide anything." } + - { id: neighbour-parking, need: objection, text: "The flats they want to build in the old grocery have four parking places for four flats and everyone here already parks on the street. I object." } + - { id: road-authority, need: hearing-answer, text: "Regarding your case 2026/418: the access onto the county road is within the sight line and we cannot accept it as drawn. Our formal reply is attached." } + - { id: fire-service, need: hearing-answer, text: "We have looked at the conversion on Torget. We have no objection provided the stairwell is upgraded. Reference your case 2026/501." } + - { id: refused-applicant, need: appeal, text: "You refused our exemption on the ninth. We don't accept the reasoning - you've allowed the same thing twice in the same street. We're appealing." } + - { id: neighbour-appeals, need: appeal, text: "You approved the extension next door even though I objected. I'm appealing the decision. What do I need to send?" } + - { id: board-member, need: appeal, text: "I sit on the appeals board. I need the case, our own decision, and what the neighbours wrote, before Tuesday." } + - { id: inspector-on-roof, need: inspection-finding, text: "I'm up on the scaffold at Bjorkeveien. The fire wall isn't built to the drawing at all. I've got gloves on and it's blowing. I want this logged before I climb down." } + - { id: inspector-all-good, need: inspection-finding, text: "Been out at Torget. Everything is as approved. Nothing to report but I have to record that I was there." } + - { id: firm-wants-certificate, need: completion-request, text: "The work at Bjorkeveien 14 is finished and inspected. We're asking for the completion certificate so the owners can get their mortgage released." } + - { id: wants-to-move-in, need: completion-request, text: "The house is done apart from the outside steps, which we can't pour until spring. The family has sold their flat. Can we get a temporary permission to move in?" } + - { id: something-behind-fence, need: illegal-building-report, text: "There's a large structure going up behind the fence at Solbakken 7. Nobody has had a notice about it and it's been going on for two weeks." } + - { id: owner-explains, need: illegal-building-report, text: "I got your letter about the terrace. I genuinely did not know it needed an application, it's been there since we moved in. What happens now?" } + - { id: new-firm, need: firm-approval, text: "We are a three-person architecture firm that has just started. We want to be approved so we can file applications for our clients in your municipality." } + - { id: firm-insurance-lapsed, need: firm-approval, text: "You wrote that our liability insurance certificate has expired. We have renewed it, here it is." } + - { id: counter-phone-call, need: log-counter-enquiry, text: "A woman rang about the case behind her house. Wants to know where it stands. I'm at the counter and there's a queue - I need to write it down and send it to whoever has that case." } + - { id: where-is-my-case, need: case-status-enquiry, text: "I sent in my application five weeks ago and I've heard nothing. Is anyone looking at it? Is it in the six weeks with the neighbours or is it waiting on me?" } diff --git a/runs/permits-2026-09-25/README.md b/runs/permits-2026-09-25/README.md new file mode 100644 index 0000000..a83e24c --- /dev/null +++ b/runs/permits-2026-09-25/README.md @@ -0,0 +1,183 @@ +# Vestmark kommune - Building and Planning, 2026-09-25 + +The hardest sector the trainer has been given, chosen to find where +portal stops rather than to flatter it: a municipal building authority. +Applications that pause and resume, a decision no case officer may sign, +a group outside the building that moves records and nothing else, +objections that belong to other cases, a six-week deadline nobody +presses a button for, and an appeal that reopens something already +finished. + +Built with no model in the loop: the words are the builder's own +fallbacks. What is measured here is the machinery, not the prose. + +- plan: `plans/building-permits.yaml` (14 needs, 7 groups, 12 buckets) +- intake: `intakes/building-permits.yaml` +- 41 questions, 14 aggregates, 198 access rules, 14 needs structurally met + +## What was proved + +`iris replay` runs cases through portal's own `answers::store_answer` +and `aggregates::transition`, against a throwaway JetStream in docker - +the same code the running site uses, with its event log and its refusal +of undeclared moves. Fifteen cases, each one a path a real building case +walks (`cases.jsonl`). + +| | transitions accepted | refused by the engine | +|---|---|---| +| as first built | 36 | **3, all of them legal paths** | +| hand-corrected `aggregates.yaml` | 45 | 2, both of them illegal paths | +| rebuilt from the plan, after the fix | 45 | 2, both of them illegal paths | + +The three refusals in the first row were the sector, not the site: + + REFUSED: asked-twice -> incomplete (complete -> incomplete) + REFUSED: hearing-sent-it-back -> incomplete (on_hearing -> incomplete) + REFUSED: we-changed-our-mind -> changed_by_us (reconsidered -> changed_by_us) + +and meanwhile the engine happily accepted `open -> refused` (refusing an +application on the day it arrives, before anyone has read it) and +`open -> overturned` (the appeals board overturning a case that never +reached them). + +**Portal's aggregate engine needed no change at all.** Hand-writing the +correct graph into `aggregates.yaml` - a cycle back to `incomplete`, +twice, and a success state reachable from the middle of the line - was +accepted as-is and enforced exactly. The whole gap was in the trainer's +plan language, which could only describe a line that goes forward. + +## What was fixed in the trainer + +**`reached_from`** (`src/build.rs`). Where a stage is entered from, when +the line does not say it: + +```yaml +reached_from: + incomplete: [open, complete, on_hearing] # sent back for papers + refused: [complete, on_hearing, recommended] # never on arrival +``` + +A stage named there is entered from exactly those stages and nowhere +else, so saying where a refusal may come from also says where it may +not. It covers both of the sector's shapes - a case sent back to a stage +it was already past, and a good ending partway along - and it subsumes +`turned_down_from`, which was one list for every bad end at once and so +could not say that an applicant may withdraw from anywhere while the +authority may refuse only once the papers are in. The rebuilt site now +produces exactly the hand-corrected graph, and the access policy follows +it: `section_head` gets `complete -> refused` and no longer +`open -> refused`; `appeals_board` gets only `before_the_board -> upheld` +and `-> overturned`. + +**The public-view rule is now per bucket, not per need.** A permit +register holds the owner's small application and the approved firm's +large one, and is one page either way; the old rule refused to publish +a bucket the moment any role filed into it, which made "nobody outside +this building can see a case" - the intake's own complaint - unfixable. +A bucket only a role ever writes to is still refused, and that is why +the hearing register here is internal. + +## What portal cannot do yet + +Each of these is a change **proposed, not made**. They are ordered by +how much this sector needed them. + +### 1. A submitter may only act while the record is untouched + +`src/access.rs:223` pins a `self_transition`'s from-state to `open`: + +```rust +if let Some(st) = &alt.self_transition { + let from = crate::answers::OPEN_STATE; +``` + +The runtime is already general - `self_transition_answer` passes the +record's actual state as `context.from` and asks the policy - so this is +the compiler alone. The effect is that the applicant who is written to +for a missing drawing cannot send it: `incomplete -> complete` is in the +machine and in the plan, and the policy never emits it. Everything about +staying in dialogue with a person across a case dies here. + +*Proposed:* `self_transition` takes an optional `from: [state, ...]`, +defaulting to `[open]`; `access.rs` emits one rule per from-state, and +the lint checks each named state exists and that `from -> to` is +declared in the bucket's schema. The trainer already computes the set +(`moves_of(need, SUBMITTER)`) and would just write it down. + +### 2. A record cannot belong to another record + +An objection belongs to an application. An exemption rides on one. An +appeal is against a decision; an inspection is of a case; a hearing +answer answers a hearing request. Six of this site's twelve buckets hold +records that are *about* a record in another bucket, and the only thing +joining them is a `case_number` the person types in from a letter, which +nothing validates, nothing resolves, and nothing can list. + +This is the largest structural gap, and it is why the case officer here +still cannot be shown "this application and its four objections" on one +page - the thing the intake asks for twice. + +*Proposed:* a field `type: record` with `of: `, storing a record +id, validated by the lint against the bucket and at submission against +the store; the parent's desk row then offers its children, and a public +case page can be assembled from the parent plus everything pointing at +it. This is a real piece of work and should be its own release, not a +rider. + +### 3. Nothing moves a stage except a person + +`attended_by` lets a plan *document* a stage no desk button moves - here, +the hearing's six weeks - but nothing actually moves it. The record sits +in `open` until someone notices. The intake names this as its number one +problem: "the twelve-week clock, and the fact that stopping it and +starting it again is done by hand in a spreadsheet." + +*Proposed:* a state in `aggregates.yaml` may carry `after: { days: 42, +to: no_answer }` beside its `event:` and `mail:`, and something with a +timer fires it. gdo already holds a durable consumer, already reads +content, and already sends what a state tells it to - this is the same +shape as `mail:`, one field along. + +### 4. A public view publishes the whole bucket + +`watched_by: [public]` opens every record in the bucket, including the +ones that were refused and withdrawn. For a permit register that is +roughly right and for a register of firms it is not, which is why +`firm-approval` here is not public though the list of approved firms +genuinely is. + +*Proposed:* `public: { states: [...] }` on a bucket resource. + +### 5. A need whose success is a membership cannot say so + +`firm-approval` ending in `approved` is exactly what makes a firm a +member of `approved_firms`, and therefore what lets it file a +`permit-application` at all. Today somebody invites by hand afterwards. + +*Proposed:* `grants: ` on a state, next to `mail:`, using the +invite machinery that already exists. + +## Also found + +- The planner (`portal-trainer plan`) fails with `exited with exit status: 1` + whenever `ANTHROPIC_API_KEY` is set to anything the nested CLI rejects. + `--llm 'env -u ANTHROPIC_API_KEY claude -p'` is the fix. This plan was + written by hand, so the planner has not yet been asked to produce + anything this size. +- Two needs sharing a bucket emit the submitter's rule twice; harmless, + but the access listing has duplicate rows. + +## Reproducing + +```sh +docker run -d --rm --name iris-replay -p 127.0.0.1:14222:4222 nats:2.14.6-alpine -js +portal-trainer build --plan plans/building-permits.yaml --out runs/permits-2026-09-25 --lint iris +cd runs/permits-2026-09-25 +iris check --path questions --access +iris replay --path questions --nats nats://127.0.0.1:14222 --cases cases.jsonl +``` + +`fixed/` holds the hand-corrected `aggregates.yaml` from before the +trainer could produce it, kept as the proof that portal's engine was +never the thing in the way. Point replay at a throwaway NATS, never a +site's own: it writes. diff --git a/runs/permits-2026-09-25/aggregates.yaml b/runs/permits-2026-09-25/aggregates.yaml new file mode 100644 index 0000000..e65dd76 --- /dev/null +++ b/runs/permits-2026-09-25/aggregates.yaml @@ -0,0 +1,653 @@ +aggregates: +- bucket: appeals + initial: open + states: + open: + event: received + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Open' + body: |- + Hello, + + We have received what you sent about the decision looked at again, by us and then by the board. + + What you can do next: {site}/decide/appeal?chain={chain}&email={email} + + Solveig Hauge at byggesak@vestmark.example + reconsidered: + event: reconsidered + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Reconsidered' + body: |- + Hello, + + What you sent about the decision looked at again, by us and then by the board is now we are looking at it again. + + What you can do next: {site}/decide/appeal?chain={chain}&email={email} + + Solveig Hauge at byggesak@vestmark.example + changed_by_us: + event: changed_by_us + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Changed by us' + body: |- + Hello, + + What you sent about the decision looked at again, by us and then by the board is now we changed our own decision. + + Solveig Hauge at byggesak@vestmark.example + before_the_board: + event: before_the_board + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Before the board' + body: |- + Hello, + + What you sent about the decision looked at again, by us and then by the board is now with the appeals board. + + What you can do next: {site}/decide/appeal?chain={chain}&email={email} + + Solveig Hauge at byggesak@vestmark.example + upheld: + event: upheld + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Upheld' + body: |- + Hello, + + What you sent about the decision looked at again, by us and then by the board is now the board kept our decision. + + Solveig Hauge at byggesak@vestmark.example + overturned: + event: overturned + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Overturned' + body: |- + Hello, + + What you sent about the decision looked at again, by us and then by the board is now the board overturned us. + + Solveig Hauge at byggesak@vestmark.example + withdrawn: + event: withdrawn + transitions: + before_the_board: + - withdrawn + - overturned + - upheld + open: + - reconsidered + - withdrawn + reconsidered: + - before_the_board + - withdrawn + - changed_by_us +- bucket: applications + initial: open + states: + open: + event: received + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Open' + body: |- + Hello, + + We have received what you sent about permission to build it, and to know where the case stands. + + What you can do next: {site}/decide/small-works-application?chain={chain}&email={email} + + Solveig Hauge at byggesak@vestmark.example + incomplete: + event: incomplete + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Incomplete' + body: |- + Hello, + + What you sent about permission to build it, and to know where the case stands is now papers missing. + + What you can do next: {site}/decide/small-works-application?chain={chain}&email={email} + + Solveig Hauge at byggesak@vestmark.example + complete: + event: complete + on_hearing: + event: on_hearing + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: On hearing' + body: |- + Hello, + + What you sent about permission to build it, and to know where the case stands is now out to the neighbours and the agencies. + + What you can do next: {site}/decide/small-works-application?chain={chain}&email={email} + + Solveig Hauge at byggesak@vestmark.example + recommended: + event: recommended + approved: + event: approved + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Approved' + body: |- + Hello, + + What you sent about permission to build it, and to know where the case stands is now approved. + + Solveig Hauge at byggesak@vestmark.example + approved_with_conditions: + event: approved_with_conditions + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Approved with conditions' + body: |- + Hello, + + What you sent about permission to build it, and to know where the case stands is now approved on conditions. + + Solveig Hauge at byggesak@vestmark.example + refused: + event: refused + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Refused' + body: |- + Hello, + + What you sent about permission to build it, and to know where the case stands is now refused. + + Solveig Hauge at byggesak@vestmark.example + withdrawn: + event: withdrawn + transitions: + complete: + - on_hearing + - withdrawn + - incomplete + - refused + incomplete: + - complete + - withdrawn + on_hearing: + - recommended + - withdrawn + - incomplete + - refused + open: + - complete + - withdrawn + - incomplete + recommended: + - approved + - approved_with_conditions + - withdrawn + - refused +- bucket: completions + initial: open + states: + open: + event: received + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Open' + body: |- + Hello, + + We have received what you sent about the certificate that lets the building be used. + + Solveig Hauge at byggesak@vestmark.example + checked: + event: checked + temporary_permission: + event: temporary_permission + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Temporary permission' + body: |- + Hello, + + What you sent about the certificate that lets the building be used is now temporary permission to use. + + Solveig Hauge at byggesak@vestmark.example + certificate_issued: + event: certificate_issued + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Certificate issued' + body: |- + Hello, + + What you sent about the certificate that lets the building be used is now certificate issued. + + Solveig Hauge at byggesak@vestmark.example + refused: + event: refused + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Refused' + body: |- + Hello, + + What you sent about the certificate that lets the building be used is now refused. + + Solveig Hauge at byggesak@vestmark.example + transitions: + checked: + - temporary_permission + - certificate_issued + - refused + open: + - checked + - refused + temporary_permission: + - certificate_issued +- bucket: enquiries + initial: open + states: + open: + event: received + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Open' + body: |- + Hello, + + We have received what you sent about to be told where it actually stands. + + Solveig Hauge at byggesak@vestmark.example + in_hand: + event: in_hand + answered: + event: answered + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Answered' + body: |- + Hello, + + What you sent about to be told where it actually stands is now answered. + + Solveig Hauge at byggesak@vestmark.example + transitions: + in_hand: + - answered + open: + - in_hand +- bucket: exemptions + initial: open + states: + open: + event: received + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Open' + body: |- + Hello, + + We have received what you sent about to be allowed it anyway, with reasons on the record. + + What you can do next: {site}/decide/exemption-request?chain={chain}&email={email} + + Solveig Hauge at byggesak@vestmark.example + county_asked: + event: county_asked + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: County asked' + body: |- + Hello, + + What you sent about to be allowed it anyway, with reasons on the record is now with the county. + + What you can do next: {site}/decide/exemption-request?chain={chain}&email={email} + + Solveig Hauge at byggesak@vestmark.example + county_answered: + event: county_answered + recommended: + event: recommended + granted: + event: granted + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Granted' + body: |- + Hello, + + What you sent about to be allowed it anyway, with reasons on the record is now granted. + + Solveig Hauge at byggesak@vestmark.example + denied: + event: denied + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Denied' + body: |- + Hello, + + What you sent about to be allowed it anyway, with reasons on the record is now denied. + + Solveig Hauge at byggesak@vestmark.example + withdrawn: + event: withdrawn + transitions: + county_answered: + - recommended + - denied + - withdrawn + county_asked: + - county_answered + - denied + - withdrawn + open: + - county_asked + - denied + - withdrawn + recommended: + - granted + - denied + - withdrawn +- bucket: firms + initial: open + states: + open: + event: received + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Open' + body: |- + Hello, + + We have received what you sent about to be on the list, and then to file without asking again. + + What you can do next: {site}/decide/firm-approval?chain={chain}&email={email} + + Solveig Hauge at byggesak@vestmark.example + papers_missing: + event: papers_missing + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Papers missing' + body: |- + Hello, + + What you sent about to be on the list, and then to file without asking again is now waiting on papers. + + What you can do next: {site}/decide/firm-approval?chain={chain}&email={email} + + Solveig Hauge at byggesak@vestmark.example + checked: + event: checked + approved: + event: approved + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Approved' + body: |- + Hello, + + What you sent about to be on the list, and then to file without asking again is now approved. + + Solveig Hauge at byggesak@vestmark.example + declined: + event: declined + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Declined' + body: |- + Hello, + + What you sent about to be on the list, and then to file without asking again is now declined. + + Solveig Hauge at byggesak@vestmark.example + transitions: + checked: + - approved + - declined + open: + - papers_missing + - checked + - declined + papers_missing: + - checked + - declined +- bucket: hearing_answers + initial: open + states: + open: + event: received + read: + event: read + followed: + event: followed + set_aside: + event: set_aside + transitions: + open: + - read + - set_aside + read: + - followed + - set_aside +- bucket: hearings + initial: open + states: + open: + event: received + answered: + event: answered + no_answer: + event: no_answer + cancelled: + event: cancelled + transitions: + open: + - answered + - no_answer + - cancelled + attended_by: | + the six-week deadline: when it passes with nothing from the agency the case goes to no_answer and the application goes on without one +- bucket: illegal_building + initial: open + states: + open: + event: received + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Open' + body: |- + Hello, + + We have received what you sent about us to go and look, and to hear that we did. + + Solveig Hauge at byggesak@vestmark.example + inspected: + event: inspected + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Inspected' + body: |- + Hello, + + What you sent about us to go and look, and to hear that we did is now inspected. + + Solveig Hauge at byggesak@vestmark.example + owner_asked: + event: owner_asked + explained: + event: explained + resolved: + event: resolved + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Resolved' + body: |- + Hello, + + What you sent about us to go and look, and to hear that we did is now resolved. + + Solveig Hauge at byggesak@vestmark.example + fined: + event: fined + dropped: + event: dropped + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Dropped' + body: |- + Hello, + + What you sent about us to go and look, and to hear that we did is now nothing to pursue. + + Solveig Hauge at byggesak@vestmark.example + transitions: + explained: + - resolved + - dropped + inspected: + - owner_asked + - fined + open: + - inspected + - fined + owner_asked: + - explained +- bucket: inspections + initial: open + states: + open: + event: received + as_approved: + event: as_approved + deviation: + event: deviation + put_right: + event: put_right + escalated: + event: escalated + transitions: + deviation: + - as_approved + - put_right + - escalated + open: + - deviation + - escalated +- bucket: meetings + initial: open + states: + open: + event: received + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Open' + body: |- + Hello {name}, + + We have received what you sent about to hear what we will allow before paying an architect. + + What you can do next: {site}/decide/pre-application-meeting?chain={chain}&email={email} + + Solveig Hauge at byggesak@vestmark.example + scheduled: + event: scheduled + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Scheduled' + body: |- + Hello {name}, + + What you sent about to hear what we will allow before paying an architect is now scheduled. + + What you can do next: {site}/decide/pre-application-meeting?chain={chain}&email={email} + + Solveig Hauge at byggesak@vestmark.example + met: + event: met + advised: + event: advised + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Advised' + body: |- + Hello {name}, + + What you sent about to hear what we will allow before paying an architect is now written advice sent. + + Solveig Hauge at byggesak@vestmark.example + cancelled: + event: cancelled + transitions: + met: + - advised + - cancelled + open: + - scheduled + - cancelled + scheduled: + - met + - cancelled +- bucket: objections + initial: open + states: + open: + event: received + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Open' + body: |- + Hello, + + We have received what you sent about what they think on the record, and answered in the decision. + + What you can do next: {site}/decide/objection?chain={chain}&email={email} + + Solveig Hauge at byggesak@vestmark.example + registered: + event: registered + answered_by_applicant: + event: answered_by_applicant + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Answered by applicant' + body: |- + Hello, + + What you sent about what they think on the record, and answered in the decision is now the applicant has answered. + + What you can do next: {site}/decide/objection?chain={chain}&email={email} + + Solveig Hauge at byggesak@vestmark.example + addressed: + event: addressed + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Addressed' + body: |- + Hello, + + What you sent about what they think on the record, and answered in the decision is now answered in the decision. + + Solveig Hauge at byggesak@vestmark.example + withdrawn: + event: withdrawn + transitions: + answered_by_applicant: + - addressed + - withdrawn + open: + - registered + - withdrawn + registered: + - answered_by_applicant + - withdrawn diff --git a/runs/permits-2026-09-25/answers-full-seed1.jsonl b/runs/permits-2026-09-25/answers-full-seed1.jsonl new file mode 100644 index 0000000..4b13c63 --- /dev/null +++ b/runs/permits-2026-09-25/answers-full-seed1.jsonl @@ -0,0 +1,25 @@ +{"id":"garage-owner@/","choice":"Building near me","confidence":0.95} +{"id":"garage-owner@/want-to-build","choice":"to be allowed it anyway, with reasons on the record","confidence":0.95} +{"id":"shop-to-flats@/","choice":"Want to build","confidence":0.95} +{"id":"shop-to-flats@/want-to-build","choice":"permission to build it, and to know where the case stands","confidence":0.95} +{"id":"too-close-to-boundary@/","choice":"Want to build","confidence":0.95} +{"id":"too-close-to-boundary@/want-to-build","choice":"to be allowed it anyway, with reasons on the record","confidence":0.95} +{"id":"neighbour-view@/","choice":"the decision looked at again, by us and then by the board","confidence":0.95} +{"id":"neighbour-view@/building-near-me","choice":"what they think on the record, and answered in the decision","confidence":0.95} +{"id":"neighbour-parking@/","choice":"Building near me","confidence":0.95} +{"id":"neighbour-parking@/building-near-me","choice":"what they think on the record, and answered in the decision","confidence":0.95} +{"id":"refused-applicant@/","choice":"the decision looked at again, by us and then by the board","confidence":0.95} +{"id":"neighbour-appeals@/","choice":"the decision looked at again, by us and then by the board","confidence":0.95} +{"id":"board-member@/","choice":"the decision looked at again, by us and then by the board","confidence":0.95} +{"id":"firm-wants-certificate@/","choice":"the decision looked at again, by us and then by the board","confidence":0.95} +{"id":"firm-wants-certificate@/want-to-build","choice":"the certificate that lets the building be used","confidence":0.95} +{"id":"wants-to-move-in@/","choice":"Want to build","confidence":0.95} +{"id":"wants-to-move-in@/want-to-build","choice":"the certificate that lets the building be used","confidence":0.95} +{"id":"something-behind-fence@/","choice":"the decision looked at again, by us and then by the board","confidence":0.95} +{"id":"something-behind-fence@/building-near-me","choice":"us to go and look, and to hear that we did","confidence":0.95} +{"id":"owner-explains@/","choice":"Want to build","confidence":0.95} +{"id":"owner-explains@/building-near-me","choice":"us to go and look, and to hear that we did","confidence":0.95} +{"id":"new-firm@/","choice":"to be on the list, and then to file without asking again","confidence":1.0} +{"id":"firm-insurance-lapsed@/","choice":"to be on the list, and then to file without asking again","confidence":0.95} +{"id":"where-is-my-case@/","choice":"Building near me","confidence":0.95} +{"id":"where-is-my-case@/building-near-me","choice":"to be told where it actually stands","confidence":0.95} diff --git a/runs/permits-2026-09-25/answers-full-seed2.jsonl b/runs/permits-2026-09-25/answers-full-seed2.jsonl new file mode 100644 index 0000000..e69de29 diff --git a/runs/permits-2026-09-25/cases.jsonl b/runs/permits-2026-09-25/cases.jsonl new file mode 100644 index 0000000..6373089 --- /dev/null +++ b/runs/permits-2026-09-25/cases.jsonl @@ -0,0 +1,15 @@ +{"need":"small-works-application","persona":"straight-through","run":1,"record":{"email":"a@x.example","property_address":"Bjorkeveien 14","property_number":"42/7","what_is_planned":"A dormer window","neighbours_notified":"Yes"},"states":["open","complete","on_hearing","recommended","approved"]} +{"need":"small-works-application","persona":"asked-twice","run":1,"record":{"email":"b@x.example","property_address":"Solbakken 7","property_number":"51/2","what_is_planned":"A double garage","neighbours_notified":"Not yet"},"states":["open","incomplete","complete","incomplete","complete","on_hearing","recommended","approved_with_conditions"]} +{"need":"small-works-application","persona":"refused-on-arrival","run":1,"record":{"email":"c@x.example","property_address":"Torget 3","property_number":"12/9","what_is_planned":"Four flats in the old grocery","neighbours_notified":"Not yet"},"states":["open","refused"]} +{"need":"small-works-application","persona":"withdrawn-after-neighbours","run":1,"record":{"email":"d@x.example","property_address":"Elvegata 2","property_number":"18/4","what_is_planned":"An extension","neighbours_notified":"Yes"},"states":["open","complete","on_hearing","withdrawn"]} +{"need":"small-works-application","persona":"hearing-sent-it-back","run":1,"record":{"email":"e@x.example","property_address":"Kirkeveien 9","property_number":"7/33","what_is_planned":"A new access onto the county road","neighbours_notified":"Yes"},"states":["open","complete","on_hearing","incomplete","complete","on_hearing","recommended","approved"]} +{"need":"appeal","persona":"we-changed-our-mind","run":1,"record":{"email":"f@x.example","case_number":"2026/418","property":"Bjorkeveien 14","what_you_disagree_with":"You allowed the same thing twice in this street","your_interest":"I applied"},"states":["open","reconsidered","changed_by_us"]} +{"need":"appeal","persona":"board-upholds","run":1,"record":{"email":"g@x.example","case_number":"2026/501","property":"Torget 3","what_you_disagree_with":"The parking count is wrong","your_interest":"I am a neighbour"},"states":["open","reconsidered","before_the_board","upheld"]} +{"need":"appeal","persona":"board-overturns-unseen","run":1,"record":{"email":"h@x.example","case_number":"2026/377","property":"Solbakken 7","what_you_disagree_with":"Everything about it","your_interest":"Other"},"states":["open","overturned"]} +{"need":"completion-request","persona":"move-in-before-the-steps","run":1,"record":{"email":"i@x.example","case_number":"2026/418","property_address":"Bjorkeveien 14","work_finished":"2026-09-01","asking_for":"Temporary permission to move in"},"states":["open","checked","temporary_permission","certificate_issued"]} +{"need":"exemption-request","persona":"too-close-to-boundary","run":1,"record":{"email":"j@x.example","case_number":"2026/418","which_rule":"Four metres to the boundary","why_it_should_be_allowed":"The ground falls away everywhere else on the plot"},"states":["open","county_asked","county_answered","recommended","granted"]} +{"need":"objection","persona":"loses-the-afternoon-sun","run":1,"record":{"email":"k@x.example","case_number":"2026/418","your_property":"Bjorkeveien 16","your_objection":"It takes the sun off my whole terrace"},"states":["open","registered","answered_by_applicant","addressed"]} +{"need":"illegal-building-report","persona":"something-behind-the-fence","run":1,"record":{"email":"l@x.example","address":"Solbakken 7","what_you_saw":"A large structure, nobody was notified"},"states":["open","inspected","owner_asked","explained","resolved"]} +{"need":"request-hearing","persona":"county-never-answered","run":1,"record":{"case_number":"2026/501","which_authority":"The county","what_we_ask":"Is the access acceptable","answer_by":"2026-08-15"},"states":["open","no_answer"]} +{"need":"hearing-answer","persona":"road-authority-objects","run":1,"record":{"case_number":"2026/501","which_authority":"Road authority","our_answer":"Objection","what_we_say":"The access is within the sight line"},"states":["open","read","set_aside"]} +{"need":"inspection-finding","persona":"fire-wall-wrong","run":1,"record":{"case_number":"2026/418","site_address":"Bjorkeveien 14","what_i_found":"The fire wall is not built to the drawing"},"states":["open","deviation","put_right"]} diff --git a/runs/permits-2026-09-25/fixed/aggregates.yaml b/runs/permits-2026-09-25/fixed/aggregates.yaml new file mode 100644 index 0000000..6a01c16 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/aggregates.yaml @@ -0,0 +1,653 @@ +aggregates: +- bucket: appeals + initial: open + states: + open: + event: received + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Open' + body: |- + Hello, + + We have received what you sent about the decision looked at again, by us and then by the board. + + What you can do next: {site}/decide/appeal?chain={chain}&email={email} + + Solveig Hauge at byggesak@vestmark.example + reconsidered: + event: reconsidered + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Reconsidered' + body: |- + Hello, + + What you sent about the decision looked at again, by us and then by the board is now we are looking at it again. + + What you can do next: {site}/decide/appeal?chain={chain}&email={email} + + Solveig Hauge at byggesak@vestmark.example + changed_by_us: + event: changed_by_us + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Changed by us' + body: |- + Hello, + + What you sent about the decision looked at again, by us and then by the board is now we changed our own decision. + + Solveig Hauge at byggesak@vestmark.example + before_the_board: + event: before_the_board + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Before the board' + body: |- + Hello, + + What you sent about the decision looked at again, by us and then by the board is now with the appeals board. + + What you can do next: {site}/decide/appeal?chain={chain}&email={email} + + Solveig Hauge at byggesak@vestmark.example + upheld: + event: upheld + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Upheld' + body: |- + Hello, + + What you sent about the decision looked at again, by us and then by the board is now the board kept our decision. + + Solveig Hauge at byggesak@vestmark.example + overturned: + event: overturned + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Overturned' + body: |- + Hello, + + What you sent about the decision looked at again, by us and then by the board is now the board overturned us. + + Solveig Hauge at byggesak@vestmark.example + withdrawn: + event: withdrawn + transitions: + open: + - reconsidered + - withdrawn + reconsidered: + - changed_by_us + - before_the_board + - withdrawn + before_the_board: + - upheld + - overturned + - withdrawn +- bucket: applications + initial: open + states: + open: + event: received + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Open' + body: |- + Hello, + + We have received what you sent about permission to build it, and to know where the case stands. + + What you can do next: {site}/decide/small-works-application?chain={chain}&email={email} + + Solveig Hauge at byggesak@vestmark.example + incomplete: + event: incomplete + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Incomplete' + body: |- + Hello, + + What you sent about permission to build it, and to know where the case stands is now papers missing. + + What you can do next: {site}/decide/small-works-application?chain={chain}&email={email} + + Solveig Hauge at byggesak@vestmark.example + complete: + event: complete + on_hearing: + event: on_hearing + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: On hearing' + body: |- + Hello, + + What you sent about permission to build it, and to know where the case stands is now out to the neighbours and the agencies. + + What you can do next: {site}/decide/small-works-application?chain={chain}&email={email} + + Solveig Hauge at byggesak@vestmark.example + recommended: + event: recommended + approved: + event: approved + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Approved' + body: |- + Hello, + + What you sent about permission to build it, and to know where the case stands is now approved. + + Solveig Hauge at byggesak@vestmark.example + approved_with_conditions: + event: approved_with_conditions + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Approved with conditions' + body: |- + Hello, + + What you sent about permission to build it, and to know where the case stands is now approved on conditions. + + Solveig Hauge at byggesak@vestmark.example + refused: + event: refused + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Refused' + body: |- + Hello, + + What you sent about permission to build it, and to know where the case stands is now refused. + + Solveig Hauge at byggesak@vestmark.example + withdrawn: + event: withdrawn + transitions: + open: + - incomplete + - complete + - withdrawn + incomplete: + - complete + - withdrawn + complete: + - incomplete + - on_hearing + - refused + - withdrawn + on_hearing: + - incomplete + - recommended + - refused + - withdrawn + recommended: + - approved + - approved_with_conditions + - refused + - withdrawn +- bucket: completions + initial: open + states: + open: + event: received + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Open' + body: |- + Hello, + + We have received what you sent about the certificate that lets the building be used. + + Solveig Hauge at byggesak@vestmark.example + checked: + event: checked + temporary_permission: + event: temporary_permission + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Temporary permission' + body: |- + Hello, + + What you sent about the certificate that lets the building be used is now temporary permission to use. + + Solveig Hauge at byggesak@vestmark.example + certificate_issued: + event: certificate_issued + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Certificate issued' + body: |- + Hello, + + What you sent about the certificate that lets the building be used is now certificate issued. + + Solveig Hauge at byggesak@vestmark.example + refused: + event: refused + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Refused' + body: |- + Hello, + + What you sent about the certificate that lets the building be used is now refused. + + Solveig Hauge at byggesak@vestmark.example + transitions: + checked: + - temporary_permission + - certificate_issued + - refused + open: + - checked + - refused + temporary_permission: + - certificate_issued +- bucket: enquiries + initial: open + states: + open: + event: received + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Open' + body: |- + Hello, + + We have received what you sent about to be told where it actually stands. + + Solveig Hauge at byggesak@vestmark.example + in_hand: + event: in_hand + answered: + event: answered + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Answered' + body: |- + Hello, + + What you sent about to be told where it actually stands is now answered. + + Solveig Hauge at byggesak@vestmark.example + transitions: + in_hand: + - answered + open: + - in_hand +- bucket: exemptions + initial: open + states: + open: + event: received + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Open' + body: |- + Hello, + + We have received what you sent about to be allowed it anyway, with reasons on the record. + + What you can do next: {site}/decide/exemption-request?chain={chain}&email={email} + + Solveig Hauge at byggesak@vestmark.example + county_asked: + event: county_asked + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: County asked' + body: |- + Hello, + + What you sent about to be allowed it anyway, with reasons on the record is now with the county. + + What you can do next: {site}/decide/exemption-request?chain={chain}&email={email} + + Solveig Hauge at byggesak@vestmark.example + county_answered: + event: county_answered + recommended: + event: recommended + granted: + event: granted + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Granted' + body: |- + Hello, + + What you sent about to be allowed it anyway, with reasons on the record is now granted. + + Solveig Hauge at byggesak@vestmark.example + denied: + event: denied + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Denied' + body: |- + Hello, + + What you sent about to be allowed it anyway, with reasons on the record is now denied. + + Solveig Hauge at byggesak@vestmark.example + withdrawn: + event: withdrawn + transitions: + county_answered: + - recommended + - denied + - withdrawn + county_asked: + - county_answered + - denied + - withdrawn + open: + - county_asked + - denied + - withdrawn + recommended: + - granted + - denied + - withdrawn +- bucket: firms + initial: open + states: + open: + event: received + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Open' + body: |- + Hello, + + We have received what you sent about to be on the list, and then to file without asking again. + + What you can do next: {site}/decide/firm-approval?chain={chain}&email={email} + + Solveig Hauge at byggesak@vestmark.example + papers_missing: + event: papers_missing + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Papers missing' + body: |- + Hello, + + What you sent about to be on the list, and then to file without asking again is now waiting on papers. + + What you can do next: {site}/decide/firm-approval?chain={chain}&email={email} + + Solveig Hauge at byggesak@vestmark.example + checked: + event: checked + approved: + event: approved + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Approved' + body: |- + Hello, + + What you sent about to be on the list, and then to file without asking again is now approved. + + Solveig Hauge at byggesak@vestmark.example + declined: + event: declined + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Declined' + body: |- + Hello, + + What you sent about to be on the list, and then to file without asking again is now declined. + + Solveig Hauge at byggesak@vestmark.example + transitions: + checked: + - approved + - declined + open: + - papers_missing + - checked + - declined + papers_missing: + - checked + - declined +- bucket: hearing_answers + initial: open + states: + open: + event: received + read: + event: read + followed: + event: followed + set_aside: + event: set_aside + transitions: + open: + - read + - set_aside + read: + - followed + - set_aside +- bucket: hearings + initial: open + states: + open: + event: received + answered: + event: answered + no_answer: + event: no_answer + cancelled: + event: cancelled + transitions: + open: + - answered + - no_answer + - cancelled + attended_by: | + the six-week deadline: when it passes with nothing from the agency the case goes to no_answer and the application goes on without one +- bucket: illegal_building + initial: open + states: + open: + event: received + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Open' + body: |- + Hello, + + We have received what you sent about us to go and look, and to hear that we did. + + Solveig Hauge at byggesak@vestmark.example + inspected: + event: inspected + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Inspected' + body: |- + Hello, + + What you sent about us to go and look, and to hear that we did is now inspected. + + Solveig Hauge at byggesak@vestmark.example + owner_asked: + event: owner_asked + explained: + event: explained + resolved: + event: resolved + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Resolved' + body: |- + Hello, + + What you sent about us to go and look, and to hear that we did is now resolved. + + Solveig Hauge at byggesak@vestmark.example + fined: + event: fined + dropped: + event: dropped + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Dropped' + body: |- + Hello, + + What you sent about us to go and look, and to hear that we did is now nothing to pursue. + + Solveig Hauge at byggesak@vestmark.example + transitions: + explained: + - resolved + - dropped + inspected: + - owner_asked + - fined + open: + - inspected + - fined + owner_asked: + - explained +- bucket: inspections + initial: open + states: + open: + event: received + as_approved: + event: as_approved + deviation: + event: deviation + put_right: + event: put_right + escalated: + event: escalated + transitions: + deviation: + - as_approved + - put_right + - escalated + open: + - deviation + - escalated +- bucket: meetings + initial: open + states: + open: + event: received + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Open' + body: |- + Hello {name}, + + We have received what you sent about to hear what we will allow before paying an architect. + + What you can do next: {site}/decide/pre-application-meeting?chain={chain}&email={email} + + Solveig Hauge at byggesak@vestmark.example + scheduled: + event: scheduled + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Scheduled' + body: |- + Hello {name}, + + What you sent about to hear what we will allow before paying an architect is now scheduled. + + What you can do next: {site}/decide/pre-application-meeting?chain={chain}&email={email} + + Solveig Hauge at byggesak@vestmark.example + met: + event: met + advised: + event: advised + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Advised' + body: |- + Hello {name}, + + What you sent about to hear what we will allow before paying an architect is now written advice sent. + + Solveig Hauge at byggesak@vestmark.example + cancelled: + event: cancelled + transitions: + met: + - advised + - cancelled + open: + - scheduled + - cancelled + scheduled: + - met + - cancelled +- bucket: objections + initial: open + states: + open: + event: received + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Open' + body: |- + Hello, + + We have received what you sent about what they think on the record, and answered in the decision. + + What you can do next: {site}/decide/objection?chain={chain}&email={email} + + Solveig Hauge at byggesak@vestmark.example + registered: + event: registered + answered_by_applicant: + event: answered_by_applicant + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Answered by applicant' + body: |- + Hello, + + What you sent about what they think on the record, and answered in the decision is now the applicant has answered. + + What you can do next: {site}/decide/objection?chain={chain}&email={email} + + Solveig Hauge at byggesak@vestmark.example + addressed: + event: addressed + mail: + to: submitter + subject: 'Vestmark kommune - Building and Planning: Addressed' + body: |- + Hello, + + What you sent about what they think on the record, and answered in the decision is now answered in the decision. + + Solveig Hauge at byggesak@vestmark.example + withdrawn: + event: withdrawn + transitions: + answered_by_applicant: + - addressed + - withdrawn + open: + - registered + - withdrawn + registered: + - answered_by_applicant + - withdrawn diff --git a/runs/permits-2026-09-25/fixed/needs.yaml b/runs/permits-2026-09-25/fixed/needs.yaml new file mode 100644 index 0000000..0f4deac --- /dev/null +++ b/runs/permits-2026-09-25/fixed/needs.yaml @@ -0,0 +1,430 @@ +needs: +- id: pre-application-meeting + who: someone with an idea for a building and no drawings yet + wants: to hear what we will allow before paying an architect + enters: / + via: Want to build + lands_in: meetings + handled_by: case_officers + stages: + - open + - scheduled + - met + - advised + - cancelled + done_when: + - advised + - cancelled + success: + - advised + max_steps: 2 + max_fields: 5 + stage_words: + open: open + scheduled: scheduled + met: we have met + advised: written advice sent + cancelled: cancelled + also_moved_by: + - front_desk +- id: small-works-application + who: an owner applying for something small enough to file themselves + wants: permission to build it, and to know where the case stands + enters: / + via: Want to build + lands_in: applications + handled_by: case_officers + stages: + - open + - incomplete + - complete + - on_hearing + - recommended + - approved + - approved_with_conditions + - refused + - withdrawn + done_when: + - approved + - approved_with_conditions + - refused + - withdrawn + success: + - approved + - approved_with_conditions + max_steps: 2 + max_fields: 6 + stage_words: + open: open + incomplete: papers missing + complete: papers complete + on_hearing: out to the neighbours and the agencies + recommended: recommendation written + approved: approved + approved_with_conditions: approved on conditions + refused: refused + withdrawn: withdrawn + also_moved_by: + - section_head +- id: exemption-request + who: someone whose plans break a rule in the zoning map + wants: to be allowed it anyway, with reasons on the record + enters: / + via: Want to build + lands_in: exemptions + handled_by: case_officers + stages: + - open + - county_asked + - county_answered + - recommended + - granted + - denied + - withdrawn + done_when: + - granted + - denied + - withdrawn + success: + - granted + max_steps: 2 + max_fields: 4 + stage_words: + open: open + county_asked: with the county + county_answered: the county has answered + recommended: recommended + granted: granted + denied: denied + withdrawn: withdrawn + also_moved_by: + - agencies + - section_head +- id: completion-request + who: an owner or firm whose building work is finished + wants: the certificate that lets the building be used + enters: / + via: Want to build + lands_in: completions + handled_by: case_officers + stages: + - open + - checked + - temporary_permission + - certificate_issued + - refused + done_when: + - certificate_issued + - refused + success: + - certificate_issued + max_steps: 2 + max_fields: 5 + stage_words: + open: open + checked: checked against the inspections + temporary_permission: temporary permission to use + certificate_issued: certificate issued + refused: refused + also_moved_by: + - section_head +- id: objection + who: a neighbour who got a notice about what is planned next door + wants: what they think on the record, and answered in the decision + enters: / + via: Building near me + lands_in: objections + handled_by: case_officers + stages: + - open + - registered + - answered_by_applicant + - addressed + - withdrawn + done_when: + - addressed + - withdrawn + success: + - addressed + max_steps: 2 + max_fields: 4 + stage_words: + open: open + registered: on the case file + answered_by_applicant: the applicant has answered + addressed: answered in the decision + withdrawn: withdrawn + also_moved_by: + - approved_firms +- id: case-status-enquiry + who: someone waiting on a case and getting nothing back + wants: to be told where it actually stands + enters: / + via: Building near me + lands_in: enquiries + handled_by: front_desk + stages: + - open + - in_hand + - answered + done_when: + - answered + success: + - answered + max_steps: 2 + max_fields: 3 + stage_words: + open: open + in_hand: in hand + answered: answered + also_moved_by: + - case_officers +- id: illegal-building-report + who: someone who can see building going up that nobody was told about + wants: us to go and look, and to hear that we did + enters: / + via: Building near me + lands_in: illegal_building + handled_by: inspectors + stages: + - open + - inspected + - owner_asked + - explained + - resolved + - fined + - dropped + done_when: + - resolved + - fined + - dropped + success: + - resolved + - dropped + max_steps: 2 + max_fields: 3 + stage_words: + open: open + inspected: inspected + owner_asked: the owner has been written to + explained: the owner has answered + resolved: resolved + fined: fined + dropped: nothing to pursue + also_moved_by: + - case_officers + - section_head +- id: appeal + who: anyone with an interest who will not accept a decision of ours + wants: the decision looked at again, by us and then by the board + enters: / + via: the decision looked at again, by us and then by the board + lands_in: appeals + handled_by: case_officers + stages: + - open + - reconsidered + - changed_by_us + - before_the_board + - upheld + - overturned + - withdrawn + done_when: + - changed_by_us + - upheld + - overturned + - withdrawn + success: + - changed_by_us + - upheld + max_steps: 1 + max_fields: 5 + stage_words: + open: open + reconsidered: we are looking at it again + changed_by_us: we changed our own decision + before_the_board: with the appeals board + upheld: the board kept our decision + overturned: the board overturned us + withdrawn: withdrawn + also_moved_by: + - appeals_board + - section_head +- id: firm-approval + who: an architect or engineering firm that files for its clients + wants: to be on the list, and then to file without asking again + enters: / + via: to be on the list, and then to file without asking again + lands_in: firms + handled_by: case_officers + stages: + - open + - papers_missing + - checked + - approved + - declined + done_when: + - approved + - declined + success: + - approved + max_steps: 1 + max_fields: 6 + stage_words: + open: open + papers_missing: waiting on papers + checked: papers checked + approved: approved + declined: declined + also_moved_by: + - section_head +- id: permit-application + who: an approved firm filing on behalf of an owner + wants: a decision inside twelve weeks, and to know when the clock stops + enters: /approved_firms/permit-application + via: a decision inside twelve weeks, and to know when the clock stops + lands_in: applications + handled_by: case_officers + stages: + - open + - incomplete + - complete + - on_hearing + - recommended + - approved + - approved_with_conditions + - refused + - withdrawn + done_when: + - approved + - approved_with_conditions + - refused + - withdrawn + success: + - approved + - approved_with_conditions + max_steps: 1 + max_fields: 6 + stage_words: + open: open + incomplete: papers missing + complete: papers complete + on_hearing: out to the neighbours and the agencies + recommended: recommendation written + approved: approved + approved_with_conditions: approved on conditions + refused: refused + withdrawn: withdrawn + enters_as: approved_firms + also_moved_by: + - section_head +- id: log-counter-enquiry + who: whoever is on the counter with a queue and a caller on the line + wants: the question written down and sent to whoever has the case + enters: /front_desk/log-counter-enquiry + via: the question written down and sent to whoever has the case + lands_in: enquiries + handled_by: front_desk + stages: + - open + - in_hand + - answered + done_when: + - answered + success: + - answered + max_steps: 1 + max_fields: 3 + stage_words: + open: open + in_hand: in hand + answered: answered + enters_as: front_desk + also_moved_by: + - case_officers +- id: request-hearing + who: a case officer sending a case out to the authority that must see it + wants: an answer by the deadline, or a record that none came + enters: /case_officers/request-hearing + via: an answer by the deadline, or a record that none came + lands_in: hearings + handled_by: case_officers + stages: + - open + - answered + - no_answer + - cancelled + done_when: + - answered + - no_answer + - cancelled + success: + - answered + max_steps: 1 + max_fields: 4 + stage_words: + open: open + answered: answered + no_answer: the deadline passed with no answer + cancelled: cancelled + enters_as: case_officers + also_moved_by: + - agencies +- id: hearing-answer + who: a road, fire, heritage or county officer who has been asked about a case + wants: their answer on the file, in their own words + enters: /agencies/hearing-answer + via: their answer on the file, in their own words + lands_in: hearing_answers + handled_by: case_officers + stages: + - open + - read + - followed + - set_aside + done_when: + - followed + - set_aside + success: + - followed + max_steps: 1 + max_fields: 4 + stage_words: + open: open + read: read by the case officer + followed: followed in the decision + set_aside: set aside with reasons + enters_as: agencies +- id: inspection-finding + who: an inspector on a scaffold with gloves on and the wind blowing + wants: what they found logged before they climb down + enters: /inspectors/inspection-finding + via: what they found logged before they climb down + lands_in: inspections + handled_by: inspectors + stages: + - open + - as_approved + - deviation + - put_right + - escalated + done_when: + - as_approved + - put_right + - escalated + success: + - as_approved + - put_right + max_steps: 1 + max_fields: 3 + stage_words: + open: open + as_approved: built as approved + deviation: built differently + put_right: put right + escalated: handed to a case officer + enters_as: inspectors + also_moved_by: + - case_officers + - section_head +personas: [] diff --git a/runs/permits-2026-09-25/fixed/questions/agencies/_section.yaml b/runs/permits-2026-09-25/fixed/questions/agencies/_section.yaml new file mode 100644 index 0000000..71cfb91 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/agencies/_section.yaml @@ -0,0 +1 @@ +qualifies: agencies diff --git a/runs/permits-2026-09-25/fixed/questions/agencies/hearing-answer-sent.yaml b/runs/permits-2026-09-25/fixed/questions/agencies/hearing-answer-sent.yaml new file mode 100644 index 0000000..8bc747e --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/agencies/hearing-answer-sent.yaml @@ -0,0 +1,10 @@ +name: What happens now? +description: It has reached our case officers. +alternatives: +- name: We read it and come back to you + description: Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example. +- name: Back + description: '' + action: /agencies + consequence: + - Back diff --git a/runs/permits-2026-09-25/fixed/questions/agencies/hearing-answer.yaml b/runs/permits-2026-09-25/fixed/questions/agencies/hearing-answer.yaml new file mode 100644 index 0000000..23c7b7e --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/agencies/hearing-answer.yaml @@ -0,0 +1,46 @@ +followup: false +name: Hearing answer? +description: '' +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: their answer on the file, in their own words + description: For a road, fire, heritage or county officer who has been asked about a case. + action: /agencies/hearing-answer-sent + consequence: + - Send + record_as: hearing_answers + features: + - name: What you need + description: The hearing letter we sent you, which has the case number on it. + icon: lucide:key + - name: What happens next + description: It is open, then read by the case officer, and ends followed in the decision or set aside with reasons. + icon: lucide:route + - name: Who reads it + description: Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example. + icon: lucide:users + - name: Details + requirements: + - name: case_number + label: Case number + type: text + - name: which_authority + label: Which authority + type: select + options: + - Road authority + - Fire service + - Heritage office + - The county + - name: our_answer + label: Our answer + type: select + options: + - No objection + - Objection + - Conditions required + - name: what_we_say + label: What we say + type: textarea diff --git a/runs/permits-2026-09-25/fixed/questions/agencies/index.yaml b/runs/permits-2026-09-25/fixed/questions/agencies/index.yaml new file mode 100644 index 0000000..485074a --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/agencies/index.yaml @@ -0,0 +1,78 @@ +name: What needs doing? +description: Everything hearing bodies looks after. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: Exemptions + description: Sent in by someone whose plans break a rule in the zoning map. + action: /agencies + consequence: + - Confirm + features: + - name: Exemptions + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: exemptions + requires_group: agencies + transitions: + - from: county_asked + to: county_answered + label: The county has answered +- name: Hearings + description: Sent in by a case officer sending a case out to the authority that must see it. + action: /agencies + consequence: + - Confirm + features: + - name: Hearings + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: hearings + requires_group: agencies + transitions: + - from: open + to: answered + label: Answered +- name: their answer on the file, in their own words + description: For a road, fire, heritage or county officer who has been asked about a case. + action: /agencies/hearing-answer + consequence: + - Open +- name: Invite someone into Hearing bodies + description: They get an account, a place in Hearing bodies, and a one-time link to set their own password or passkey. + action: /agencies + consequence: + - Invite + invite: + group: agencies + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invitations sent + description: Each invite with the link it made. Mark it done when the person is in. + action: /agencies + consequence: + - Confirm + features: + - name: Who has been invited + description: Each row is one invitation, with the one-time link while it is unused. + resource: + source: + kind: kv + bucket: portal_invites + requires_group: agencies + transitions: + - from: open + to: done + label: Is in diff --git a/runs/permits-2026-09-25/fixed/questions/appeals_board/_section.yaml b/runs/permits-2026-09-25/fixed/questions/appeals_board/_section.yaml new file mode 100644 index 0000000..a23502c --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/appeals_board/_section.yaml @@ -0,0 +1 @@ +qualifies: appeals_board diff --git a/runs/permits-2026-09-25/fixed/questions/appeals_board/index.yaml b/runs/permits-2026-09-25/fixed/questions/appeals_board/index.yaml new file mode 100644 index 0000000..e3aa2d2 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/appeals_board/index.yaml @@ -0,0 +1,65 @@ +name: What needs doing? +description: Everything appeals board looks after. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: Appeals + description: Sent in by anyone with an interest who will not accept a decision of ours. + action: /appeals_board + consequence: + - Confirm + features: + - name: Appeals + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: appeals + requires_group: appeals_board + transitions: + - from: before_the_board + to: upheld + label: The board kept our decision + - from: before_the_board + to: overturned + label: The board overturned us + - from: open + to: overturned + label: The board overturned us + - from: reconsidered + to: overturned + label: The board overturned us +- name: Invite someone into Appeals board + description: They get an account, a place in Appeals board, and a one-time link to set their own password or passkey. + action: /appeals_board + consequence: + - Invite + invite: + group: appeals_board + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invitations sent + description: Each invite with the link it made. Mark it done when the person is in. + action: /appeals_board + consequence: + - Confirm + features: + - name: Who has been invited + description: Each row is one invitation, with the one-time link while it is unused. + resource: + source: + kind: kv + bucket: portal_invites + requires_group: appeals_board + transitions: + - from: open + to: done + label: Is in diff --git a/runs/permits-2026-09-25/fixed/questions/approved_firms/_section.yaml b/runs/permits-2026-09-25/fixed/questions/approved_firms/_section.yaml new file mode 100644 index 0000000..85f1f10 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/approved_firms/_section.yaml @@ -0,0 +1 @@ +qualifies: approved_firms diff --git a/runs/permits-2026-09-25/fixed/questions/approved_firms/index.yaml b/runs/permits-2026-09-25/fixed/questions/approved_firms/index.yaml new file mode 100644 index 0000000..bc823e4 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/approved_firms/index.yaml @@ -0,0 +1,61 @@ +name: What needs doing? +description: Everything approved firms looks after. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: Objections + description: Sent in by a neighbour who got a notice about what is planned next door. + action: /approved_firms + consequence: + - Confirm + features: + - name: Objections + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: objections + requires_group: approved_firms + transitions: + - from: registered + to: answered_by_applicant + label: The applicant has answered +- name: a decision inside twelve weeks, and to know when the clock stops + description: For an approved firm filing on behalf of an owner. + action: /approved_firms/permit-application + consequence: + - Open +- name: Invite someone into Approved firms + description: They get an account, a place in Approved firms, and a one-time link to set their own password or passkey. + action: /approved_firms + consequence: + - Invite + invite: + group: approved_firms + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invitations sent + description: Each invite with the link it made. Mark it done when the person is in. + action: /approved_firms + consequence: + - Confirm + features: + - name: Who has been invited + description: Each row is one invitation, with the one-time link while it is unused. + resource: + source: + kind: kv + bucket: portal_invites + requires_group: approved_firms + transitions: + - from: open + to: done + label: Is in diff --git a/runs/permits-2026-09-25/fixed/questions/approved_firms/permit-application-sent.yaml b/runs/permits-2026-09-25/fixed/questions/approved_firms/permit-application-sent.yaml new file mode 100644 index 0000000..6914aa3 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/approved_firms/permit-application-sent.yaml @@ -0,0 +1,15 @@ +name: What happens now? +description: It has reached our case officers. +alternatives: +- name: We read it and come back to you + description: Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example. +- name: See all applications + description: '' + action: /status/applications + consequence: + - Open +- name: Back + description: '' + action: /approved_firms + consequence: + - Back diff --git a/runs/permits-2026-09-25/fixed/questions/approved_firms/permit-application.yaml b/runs/permits-2026-09-25/fixed/questions/approved_firms/permit-application.yaml new file mode 100644 index 0000000..50d5e38 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/approved_firms/permit-application.yaml @@ -0,0 +1,48 @@ +followup: false +name: Permit application? +description: '' +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: a decision inside twelve weeks, and to know when the clock stops + description: For an approved firm filing on behalf of an owner. + action: /approved_firms/permit-application-sent + consequence: + - Send + record_as: applications + features: + - name: What happens next + description: It is open, then papers missing, then papers complete, then out to the neighbours and the agencies, then recommendation written, and ends approved, approved on conditions, refused or withdrawn. + icon: lucide:route + - name: Who reads it + description: Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example. + icon: lucide:users + - name: Details + requirements: + - name: email + label: Email + type: email + - name: property_address + label: Property address + type: text + - name: property_number + label: Property number + type: text + - name: what_is_planned + label: What is planned + type: textarea + - name: neighbours_notified + label: Neighbours notified + type: select + options: + - Yes + - Not yet + - name: site + label: Site + type: location + optional: true + - name: drawings_url + label: Drawings url + type: text + optional: true diff --git a/runs/permits-2026-09-25/fixed/questions/building-near-me/index.yaml b/runs/permits-2026-09-25/fixed/questions/building-near-me/index.yaml new file mode 100644 index 0000000..caf6e50 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/building-near-me/index.yaml @@ -0,0 +1,88 @@ +name: What do you need? +description: For someone who lives next to what is being built. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: what they think on the record, and answered in the decision + description: For a neighbour who got a notice about what is planned next door. + action: /received/objection + consequence: + - Send + record_as: objections + features: + - name: What you need + description: The notice that came in the post, which has the case number on it. + icon: lucide:key + - name: What happens next + description: It is open, then on the case file, then the applicant has answered, and ends answered in the decision or withdrawn. + icon: lucide:route + - name: Who reads it + description: Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example. + icon: lucide:users + - name: Details + requirements: + - name: email + label: Email + type: email + - name: case_number + label: Case number + type: text + - name: your_property + label: Your property + type: text + - name: your_objection + label: Your objection + type: textarea +- name: to be told where it actually stands + description: For someone waiting on a case and getting nothing back. + action: /received/case-status-enquiry + consequence: + - Send + record_as: enquiries + features: + - name: What happens next + description: It is open, then in hand, and ends answered. + icon: lucide:route + - name: Who reads it + description: Front desk. Questions go to Solveig Hauge at byggesak@vestmark.example. + icon: lucide:users + - name: Details + requirements: + - name: email + label: Email + type: email + - name: case_number_or_address + label: Case number or address + type: text + - name: what_you_want_to_know + label: What you want to know + type: textarea +- name: us to go and look, and to hear that we did + description: For someone who can see building going up that nobody was told about. + action: /received/illegal-building-report + consequence: + - Send + record_as: illegal_building + features: + - name: What happens next + description: It is open, then inspected, then the owner has been written to, then the owner has answered, and ends resolved, fined or nothing to pursue. + icon: lucide:route + - name: Who reads it + description: Inspectors. Questions go to Solveig Hauge at byggesak@vestmark.example. + icon: lucide:users + - name: Details + requirements: + - name: email + label: Email + type: email + - name: address + label: Address + type: text + - name: what_you_saw + label: What you saw + type: textarea + - name: where + label: Where + type: location + optional: true diff --git a/runs/permits-2026-09-25/fixed/questions/case_officers/_section.yaml b/runs/permits-2026-09-25/fixed/questions/case_officers/_section.yaml new file mode 100644 index 0000000..0eb3949 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/case_officers/_section.yaml @@ -0,0 +1 @@ +qualifies: case_officers diff --git a/runs/permits-2026-09-25/fixed/questions/case_officers/index.yaml b/runs/permits-2026-09-25/fixed/questions/case_officers/index.yaml new file mode 100644 index 0000000..162a617 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/case_officers/index.yaml @@ -0,0 +1,395 @@ +name: What needs doing? +description: Everything case officers looks after. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: Appeals + description: Sent in by anyone with an interest who will not accept a decision of ours. + action: /case_officers + consequence: + - Confirm + features: + - name: Appeals + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: appeals + requires_group: case_officers + transitions: + - from: open + to: reconsidered + label: We are looking at it again +- name: Applications + description: Sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner. + action: /case_officers + consequence: + - Confirm + features: + - name: Applications + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: applications + requires_group: case_officers + transitions: + - from: complete + to: on_hearing + label: Out to the neighbours and the agencies + - from: incomplete + to: complete + label: Papers complete + - from: on_hearing + to: recommended + label: Recommendation written + - from: open + to: incomplete + label: Papers missing + - from: open + to: complete + label: Papers complete +- name: Completions + description: Sent in by an owner or firm whose building work is finished. + action: /case_officers + consequence: + - Confirm + features: + - name: Completions + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: completions + requires_group: case_officers + transitions: + - from: open + to: checked + label: Checked against the inspections +- name: Enquiries + description: Sent in by someone waiting on a case and getting nothing back or whoever is on the counter with a queue and a caller on the line. + action: /case_officers + consequence: + - Confirm + features: + - name: Enquiries + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: enquiries + requires_group: case_officers + transitions: + - from: open + to: in_hand + label: In hand +- name: Exemptions + description: Sent in by someone whose plans break a rule in the zoning map. + action: /case_officers + consequence: + - Confirm + features: + - name: Exemptions + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: exemptions + requires_group: case_officers + transitions: + - from: county_answered + to: recommended + label: Recommended + - from: open + to: county_asked + label: With the county +- name: Firms + description: Sent in by an architect or engineering firm that files for its clients. + action: /case_officers + consequence: + - Confirm + features: + - name: Firms + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: firms + requires_group: case_officers + transitions: + - from: open + to: papers_missing + label: Waiting on papers + - from: open + to: checked + label: Papers checked + - from: papers_missing + to: checked + label: Papers checked +- name: Hearing answers + description: Sent in by a road, fire, heritage or county officer who has been asked about a case. + action: /case_officers + consequence: + - Confirm + features: + - name: Hearing answers + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: hearing_answers + requires_group: case_officers + transitions: + - from: open + to: read + label: Read by the case officer + - from: open + to: set_aside + label: Set aside with reasons + - from: read + to: followed + label: Followed in the decision + - from: read + to: set_aside + label: Set aside with reasons +- name: Hearings + description: Sent in by a case officer sending a case out to the authority that must see it. + action: /case_officers + consequence: + - Confirm + features: + - name: Hearings + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: hearings + requires_group: case_officers + transitions: + - from: open + to: no_answer + label: The deadline passed with no answer + - from: open + to: cancelled + label: Cancelled +- name: Illegal building + description: Sent in by someone who can see building going up that nobody was told about. + action: /case_officers + consequence: + - Confirm + features: + - name: Illegal building + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: illegal_building + requires_group: case_officers + transitions: + - from: inspected + to: owner_asked + label: The owner has been written to + - from: owner_asked + to: explained + label: The owner has answered +- name: Inspections + description: Sent in by an inspector on a scaffold with gloves on and the wind blowing. + action: /case_officers + consequence: + - Confirm + features: + - name: Inspections + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: inspections + requires_group: case_officers + transitions: + - from: deviation + to: escalated + label: Handed to a case officer + - from: open + to: escalated + label: Handed to a case officer +- name: Meetings + description: Sent in by someone with an idea for a building and no drawings yet. + action: /case_officers + consequence: + - Confirm + features: + - name: Meetings + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: meetings + requires_group: case_officers + transitions: + - from: met + to: advised + label: Written advice sent + - from: open + to: scheduled + label: Scheduled + - from: scheduled + to: met + label: We have met +- name: Objections + description: Sent in by a neighbour who got a notice about what is planned next door. + action: /case_officers + consequence: + - Confirm + features: + - name: Objections + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: objections + requires_group: case_officers + transitions: + - from: answered_by_applicant + to: addressed + label: Answered in the decision + - from: open + to: registered + label: On the case file + - from: registered + to: answered_by_applicant + label: The applicant has answered +- name: an answer by the deadline, or a record that none came + description: For a case officer sending a case out to the authority that must see it. + action: /case_officers/request-hearing + consequence: + - Open +- name: Invite someone into Hearing bodies + description: They get an account, a place in Hearing bodies, and a one-time link to set their own password or passkey. + action: /case_officers + consequence: + - Invite + invite: + group: agencies + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invite someone into Appeals board + description: They get an account, a place in Appeals board, and a one-time link to set their own password or passkey. + action: /case_officers + consequence: + - Invite + invite: + group: appeals_board + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invite someone into Approved firms + description: They get an account, a place in Approved firms, and a one-time link to set their own password or passkey. + action: /case_officers + consequence: + - Invite + invite: + group: approved_firms + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invite someone into Case officers + description: They get an account, a place in Case officers, and a one-time link to set their own password or passkey. + action: /case_officers + consequence: + - Invite + invite: + group: case_officers + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invite someone into Front desk + description: They get an account, a place in Front desk, and a one-time link to set their own password or passkey. + action: /case_officers + consequence: + - Invite + invite: + group: front_desk + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invite someone into Inspectors + description: They get an account, a place in Inspectors, and a one-time link to set their own password or passkey. + action: /case_officers + consequence: + - Invite + invite: + group: inspectors + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invite someone into Head of section + description: They get an account, a place in Head of section, and a one-time link to set their own password or passkey. + action: /case_officers + consequence: + - Invite + invite: + group: section_head + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invitations sent + description: Each invite with the link it made. Mark it done when the person is in. + action: /case_officers + consequence: + - Confirm + features: + - name: Who has been invited + description: Each row is one invitation, with the one-time link while it is unused. + resource: + source: + kind: kv + bucket: portal_invites + requires_group: case_officers + transitions: + - from: open + to: done + label: Is in diff --git a/runs/permits-2026-09-25/fixed/questions/case_officers/request-hearing-sent.yaml b/runs/permits-2026-09-25/fixed/questions/case_officers/request-hearing-sent.yaml new file mode 100644 index 0000000..9a588a6 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/case_officers/request-hearing-sent.yaml @@ -0,0 +1,10 @@ +name: What happens now? +description: It has reached our case officers. +alternatives: +- name: We read it and come back to you + description: Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example. +- name: Back + description: '' + action: /case_officers + consequence: + - Back diff --git a/runs/permits-2026-09-25/fixed/questions/case_officers/request-hearing.yaml b/runs/permits-2026-09-25/fixed/questions/case_officers/request-hearing.yaml new file mode 100644 index 0000000..7bd9196 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/case_officers/request-hearing.yaml @@ -0,0 +1,43 @@ +followup: false +name: Request hearing? +description: '' +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: an answer by the deadline, or a record that none came + description: For a case officer sending a case out to the authority that must see it. + action: /case_officers/request-hearing-sent + consequence: + - Send + record_as: hearings + features: + - name: What happens next + description: It is open, and ends answered, the deadline passed with no answer or cancelled. + icon: lucide:route + - name: Who reads it + description: Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example. + icon: lucide:users + - name: Details + requirements: + - name: case_number + label: Case number + type: text + - name: which_authority + label: Which authority + type: select + options: + - Road authority + - Fire service + - Heritage office + - The county + - name: what_we_ask + label: What we ask + type: textarea + - name: answer_by + label: Answer by + type: date + - name: site + label: Site + type: location + optional: true diff --git a/runs/permits-2026-09-25/fixed/questions/decide/appeal.yaml b/runs/permits-2026-09-25/fixed/questions/decide/appeal.yaml new file mode 100644 index 0000000..9b0f503 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/decide/appeal.yaml @@ -0,0 +1,9 @@ +name: What would you like to do? +description: '' +alternatives: +- name: Withdrawn + description: '' + self_transition: + bucket: appeals + to: withdrawn + label: Withdrawn diff --git a/runs/permits-2026-09-25/fixed/questions/decide/exemption-request.yaml b/runs/permits-2026-09-25/fixed/questions/decide/exemption-request.yaml new file mode 100644 index 0000000..647cfbc --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/decide/exemption-request.yaml @@ -0,0 +1,9 @@ +name: What would you like to do? +description: '' +alternatives: +- name: Withdrawn + description: '' + self_transition: + bucket: exemptions + to: withdrawn + label: Withdrawn diff --git a/runs/permits-2026-09-25/fixed/questions/decide/firm-approval.yaml b/runs/permits-2026-09-25/fixed/questions/decide/firm-approval.yaml new file mode 100644 index 0000000..c858427 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/decide/firm-approval.yaml @@ -0,0 +1,9 @@ +name: What would you like to do? +description: '' +alternatives: +- name: Checked + description: '' + self_transition: + bucket: firms + to: checked + label: Checked diff --git a/runs/permits-2026-09-25/fixed/questions/decide/objection.yaml b/runs/permits-2026-09-25/fixed/questions/decide/objection.yaml new file mode 100644 index 0000000..7ddb909 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/decide/objection.yaml @@ -0,0 +1,9 @@ +name: What would you like to do? +description: '' +alternatives: +- name: Withdrawn + description: '' + self_transition: + bucket: objections + to: withdrawn + label: Withdrawn diff --git a/runs/permits-2026-09-25/fixed/questions/decide/permit-application.yaml b/runs/permits-2026-09-25/fixed/questions/decide/permit-application.yaml new file mode 100644 index 0000000..b90eacf --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/decide/permit-application.yaml @@ -0,0 +1,15 @@ +name: What would you like to do? +description: '' +alternatives: +- name: Complete + description: '' + self_transition: + bucket: applications + to: complete + label: Complete +- name: Withdrawn + description: '' + self_transition: + bucket: applications + to: withdrawn + label: Withdrawn diff --git a/runs/permits-2026-09-25/fixed/questions/decide/pre-application-meeting.yaml b/runs/permits-2026-09-25/fixed/questions/decide/pre-application-meeting.yaml new file mode 100644 index 0000000..315bde5 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/decide/pre-application-meeting.yaml @@ -0,0 +1,9 @@ +name: What would you like to do? +description: '' +alternatives: +- name: Cancelled + description: '' + self_transition: + bucket: meetings + to: cancelled + label: Cancelled diff --git a/runs/permits-2026-09-25/fixed/questions/decide/small-works-application.yaml b/runs/permits-2026-09-25/fixed/questions/decide/small-works-application.yaml new file mode 100644 index 0000000..b90eacf --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/decide/small-works-application.yaml @@ -0,0 +1,15 @@ +name: What would you like to do? +description: '' +alternatives: +- name: Complete + description: '' + self_transition: + bucket: applications + to: complete + label: Complete +- name: Withdrawn + description: '' + self_transition: + bucket: applications + to: withdrawn + label: Withdrawn diff --git a/runs/permits-2026-09-25/fixed/questions/front_desk/_section.yaml b/runs/permits-2026-09-25/fixed/questions/front_desk/_section.yaml new file mode 100644 index 0000000..8b76bf9 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/front_desk/_section.yaml @@ -0,0 +1 @@ +qualifies: front_desk diff --git a/runs/permits-2026-09-25/fixed/questions/front_desk/index.yaml b/runs/permits-2026-09-25/fixed/questions/front_desk/index.yaml new file mode 100644 index 0000000..b36f594 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/front_desk/index.yaml @@ -0,0 +1,157 @@ +name: What needs doing? +description: Everything front desk looks after. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: Appeals + description: Sent in by anyone with an interest who will not accept a decision of ours. + action: /front_desk + consequence: + - Confirm + features: + - name: Appeals + description: Each row is one case and the stage it has reached. Another desk moves these. + resource: + source: + kind: kv + bucket: appeals + requires_group: front_desk + transitions: [] +- name: Applications + description: Sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner. + action: /front_desk + consequence: + - Confirm + features: + - name: Applications + description: Each row is one case and the stage it has reached. Another desk moves these. + resource: + source: + kind: kv + bucket: applications + requires_group: front_desk + transitions: [] +- name: Enquiries + description: Sent in by someone waiting on a case and getting nothing back or whoever is on the counter with a queue and a caller on the line. + action: /front_desk + consequence: + - Confirm + features: + - name: Enquiries + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: enquiries + requires_group: front_desk + transitions: + - from: in_hand + to: answered + label: Answered + - from: open + to: in_hand + label: In hand +- name: Firms + description: Sent in by an architect or engineering firm that files for its clients. + action: /front_desk + consequence: + - Confirm + features: + - name: Firms + description: Each row is one case and the stage it has reached. Another desk moves these. + resource: + source: + kind: kv + bucket: firms + requires_group: front_desk + transitions: [] +- name: Hearing answers + description: Sent in by a road, fire, heritage or county officer who has been asked about a case. + action: /front_desk + consequence: + - Confirm + features: + - name: Hearing answers + description: Each row is one case and the stage it has reached. Another desk moves these. + resource: + source: + kind: kv + bucket: hearing_answers + requires_group: front_desk + transitions: [] +- name: Hearings + description: Sent in by a case officer sending a case out to the authority that must see it. + action: /front_desk + consequence: + - Confirm + features: + - name: Hearings + description: Each row is one case and the stage it has reached. Another desk moves these. + resource: + source: + kind: kv + bucket: hearings + requires_group: front_desk + transitions: [] +- name: Meetings + description: Sent in by someone with an idea for a building and no drawings yet. + action: /front_desk + consequence: + - Confirm + features: + - name: Meetings + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: meetings + requires_group: front_desk + transitions: + - from: met + to: cancelled + label: Cancelled + - from: open + to: cancelled + label: Cancelled + - from: scheduled + to: cancelled + label: Cancelled +- name: the question written down and sent to whoever has the case + description: For whoever is on the counter with a queue and a caller on the line. + action: /front_desk/log-counter-enquiry + consequence: + - Open +- name: Invite someone into Front desk + description: They get an account, a place in Front desk, and a one-time link to set their own password or passkey. + action: /front_desk + consequence: + - Invite + invite: + group: front_desk + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invitations sent + description: Each invite with the link it made. Mark it done when the person is in. + action: /front_desk + consequence: + - Confirm + features: + - name: Who has been invited + description: Each row is one invitation, with the one-time link while it is unused. + resource: + source: + kind: kv + bucket: portal_invites + requires_group: front_desk + transitions: + - from: open + to: done + label: Is in diff --git a/runs/permits-2026-09-25/fixed/questions/front_desk/log-counter-enquiry-sent.yaml b/runs/permits-2026-09-25/fixed/questions/front_desk/log-counter-enquiry-sent.yaml new file mode 100644 index 0000000..26a8dba --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/front_desk/log-counter-enquiry-sent.yaml @@ -0,0 +1,10 @@ +name: What happens now? +description: It has reached our front desk. +alternatives: +- name: We read it and come back to you + description: Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example. +- name: Back + description: '' + action: /front_desk + consequence: + - Back diff --git a/runs/permits-2026-09-25/fixed/questions/front_desk/log-counter-enquiry.yaml b/runs/permits-2026-09-25/fixed/questions/front_desk/log-counter-enquiry.yaml new file mode 100644 index 0000000..fdab619 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/front_desk/log-counter-enquiry.yaml @@ -0,0 +1,31 @@ +followup: false +name: Log counter enquiry? +description: '' +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: the question written down and sent to whoever has the case + description: For whoever is on the counter with a queue and a caller on the line. + action: /front_desk/log-counter-enquiry-sent + consequence: + - Send + record_as: enquiries + features: + - name: What happens next + description: It is open, then in hand, and ends answered. + icon: lucide:route + - name: Who reads it + description: Front desk. Questions go to Solveig Hauge at byggesak@vestmark.example. + icon: lucide:users + - name: Details + requirements: + - name: email + label: Email + type: email + - name: case_number_or_address + label: Case number or address + type: text + - name: what_you_want_to_know + label: What you want to know + type: textarea diff --git a/runs/permits-2026-09-25/fixed/questions/index.yaml b/runs/permits-2026-09-25/fixed/questions/index.yaml new file mode 100644 index 0000000..21c9960 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/index.yaml @@ -0,0 +1,127 @@ +name: What brings you here? +description: | + The building authority for twenty-one thousand people. Anything built, demolished, divided or changed in use is decided here: the drawings are checked against the zoning map, the neighbours and the other authorities have their say, and then the head of section signs. The same office inspects what is actually built, signs off finished work, and deals with building nobody applied for. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: What we do + description: '' + features: + - name: Permission to build it, and to know where the case stands + description: | + Everything built in Vestmark is decided here. You send the drawings, the neighbours and the road, fire and heritage authorities are heard, and you get a written decision you can hold us to. + - name: What they think on the record, and answered in the decision + description: | + If a notice landed in your postbox, the case behind it is open to read here, and what you write to us has to be answered by name in the decision. +- name: Have a look around + description: '' + features: + - name: See all appeals + description: Everything sent in by anyone with an interest who will not accept a decision of ours, and where each one stands. [See all appeals](/status/appeals) + icon: lucide:list + - name: See all applications + description: Everything sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner, and where each one stands. [See all applications](/status/applications) + icon: lucide:list + - name: See all completions + description: Everything sent in by an owner or firm whose building work is finished, and where each one stands. [See all completions](/status/completions) + icon: lucide:list + - name: See all exemptions + description: Everything sent in by someone whose plans break a rule in the zoning map, and where each one stands. [See all exemptions](/status/exemptions) + icon: lucide:list + - name: See all objections + description: Everything sent in by a neighbour who got a notice about what is planned next door, and where each one stands. [See all objections](/status/objections) + icon: lucide:list +- name: Want to build + description: For an owner or a firm with something to build, divide or change. + action: /want-to-build + consequence: + - Continue + features: + - name: '' + description: To hear what we will allow before paying an architect, permission to build it, and to know where the case stands, to be allowed it anyway, with reasons on the record, the certificate that lets the building be used. +- name: Building near me + description: For someone who lives next to what is being built. + action: /building-near-me + consequence: + - Continue + features: + - name: '' + description: What they think on the record, and answered in the decision, to be told where it actually stands, us to go and look, and to hear that we did. +- name: the decision looked at again, by us and then by the board + description: For anyone with an interest who will not accept a decision of ours. + action: /received/appeal + consequence: + - Send + record_as: appeals + features: + - name: What you need + description: A decision from us less than three weeks old, and its case number. + icon: lucide:key + - name: What happens next + description: It is open, then we are looking at it again, then with the appeals board, and ends we changed our own decision, the board kept our decision, the board overturned us or withdrawn. + icon: lucide:route + - name: Who reads it + description: Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example. + icon: lucide:users + - name: Details + requirements: + - name: email + label: Email + type: email + - name: case_number + label: Case number + type: text + - name: property + label: Property + type: text + - name: what_you_disagree_with + label: What you disagree with + type: textarea + - name: your_interest + label: Your interest + type: select + options: + - I applied + - I am a neighbour + - Other +- name: to be on the list, and then to file without asking again + description: For an architect or engineering firm that files for its clients. + action: /received/firm-approval + consequence: + - Send + record_as: firms + features: + - name: What happens next + description: It is open, then waiting on papers, then papers checked, and ends approved or declined. + icon: lucide:route + - name: Who reads it + description: Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example. + icon: lucide:users + - name: Details + requirements: + - name: firm_name + label: Firm name + type: text + - name: org_number + label: Org number + type: text + - name: email + label: Email + type: email + - name: qualified_for + label: Qualified for + type: select + options: + - Design + - Execution + - Independent control + - Site management + multiple: true + - name: insurance_expires + label: Insurance expires + type: date + - name: insurance_document + label: Insurance document + type: text + optional: true diff --git a/runs/permits-2026-09-25/fixed/questions/inspectors/_section.yaml b/runs/permits-2026-09-25/fixed/questions/inspectors/_section.yaml new file mode 100644 index 0000000..d41d53f --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/inspectors/_section.yaml @@ -0,0 +1 @@ +qualifies: inspectors diff --git a/runs/permits-2026-09-25/fixed/questions/inspectors/index.yaml b/runs/permits-2026-09-25/fixed/questions/inspectors/index.yaml new file mode 100644 index 0000000..f6a397a --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/inspectors/index.yaml @@ -0,0 +1,118 @@ +name: What needs doing? +description: Everything inspectors looks after. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: Applications + description: Sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner. + action: /inspectors + consequence: + - Confirm + features: + - name: Applications + description: Each row is one case and the stage it has reached. Another desk moves these. + resource: + source: + kind: kv + bucket: applications + requires_group: inspectors + transitions: [] +- name: Completions + description: Sent in by an owner or firm whose building work is finished. + action: /inspectors + consequence: + - Confirm + features: + - name: Completions + description: Each row is one case and the stage it has reached. Another desk moves these. + resource: + source: + kind: kv + bucket: completions + requires_group: inspectors + transitions: [] +- name: Illegal building + description: Sent in by someone who can see building going up that nobody was told about. + action: /inspectors + consequence: + - Confirm + features: + - name: Illegal building + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: illegal_building + requires_group: inspectors + transitions: + - from: explained + to: resolved + label: Resolved + - from: explained + to: dropped + label: Nothing to pursue + - from: open + to: inspected + label: Inspected +- name: Inspections + description: Sent in by an inspector on a scaffold with gloves on and the wind blowing. + action: /inspectors + consequence: + - Confirm + features: + - name: Inspections + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: inspections + requires_group: inspectors + transitions: + - from: deviation + to: as_approved + label: Built as approved + - from: deviation + to: put_right + label: Put right + - from: open + to: deviation + label: Built differently +- name: what they found logged before they climb down + description: For an inspector on a scaffold with gloves on and the wind blowing. + action: /inspectors/inspection-finding + consequence: + - Open +- name: Invite someone into Inspectors + description: They get an account, a place in Inspectors, and a one-time link to set their own password or passkey. + action: /inspectors + consequence: + - Invite + invite: + group: inspectors + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invitations sent + description: Each invite with the link it made. Mark it done when the person is in. + action: /inspectors + consequence: + - Confirm + features: + - name: Who has been invited + description: Each row is one invitation, with the one-time link while it is unused. + resource: + source: + kind: kv + bucket: portal_invites + requires_group: inspectors + transitions: + - from: open + to: done + label: Is in diff --git a/runs/permits-2026-09-25/fixed/questions/inspectors/inspection-finding-sent.yaml b/runs/permits-2026-09-25/fixed/questions/inspectors/inspection-finding-sent.yaml new file mode 100644 index 0000000..ac8e8b2 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/inspectors/inspection-finding-sent.yaml @@ -0,0 +1,10 @@ +name: What happens now? +description: It has reached our inspectors. +alternatives: +- name: We read it and come back to you + description: Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example. +- name: Back + description: '' + action: /inspectors + consequence: + - Back diff --git a/runs/permits-2026-09-25/fixed/questions/inspectors/inspection-finding.yaml b/runs/permits-2026-09-25/fixed/questions/inspectors/inspection-finding.yaml new file mode 100644 index 0000000..18b5d32 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/inspectors/inspection-finding.yaml @@ -0,0 +1,35 @@ +followup: false +name: Inspection finding? +description: '' +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: what they found logged before they climb down + description: For an inspector on a scaffold with gloves on and the wind blowing. + action: /inspectors/inspection-finding-sent + consequence: + - Send + record_as: inspections + features: + - name: What happens next + description: It is open, then built differently, and ends built as approved, put right or handed to a case officer. + icon: lucide:route + - name: Who reads it + description: Inspectors. Questions go to Solveig Hauge at byggesak@vestmark.example. + icon: lucide:users + - name: Details + requirements: + - name: case_number + label: Case number + type: text + - name: site_address + label: Site address + type: text + - name: what_i_found + label: What i found + type: textarea + - name: where + label: Where + type: location + optional: true diff --git a/runs/permits-2026-09-25/fixed/questions/received/appeal.yaml b/runs/permits-2026-09-25/fixed/questions/received/appeal.yaml new file mode 100644 index 0000000..6148787 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/received/appeal.yaml @@ -0,0 +1,15 @@ +name: What happens now? +description: It has reached our case officers. +alternatives: +- name: We read it and come back to you + description: Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example. +- name: See all appeals + description: '' + action: /status/appeals + consequence: + - Open +- name: Back + description: '' + action: / + consequence: + - Back diff --git a/runs/permits-2026-09-25/fixed/questions/received/case-status-enquiry.yaml b/runs/permits-2026-09-25/fixed/questions/received/case-status-enquiry.yaml new file mode 100644 index 0000000..7150e83 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/received/case-status-enquiry.yaml @@ -0,0 +1,10 @@ +name: What happens now? +description: It has reached our front desk. +alternatives: +- name: We read it and come back to you + description: Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example. +- name: Back + description: '' + action: / + consequence: + - Back diff --git a/runs/permits-2026-09-25/fixed/questions/received/completion-request.yaml b/runs/permits-2026-09-25/fixed/questions/received/completion-request.yaml new file mode 100644 index 0000000..93e37f8 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/received/completion-request.yaml @@ -0,0 +1,15 @@ +name: What happens now? +description: It has reached our case officers. +alternatives: +- name: We read it and come back to you + description: Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example. +- name: See all completions + description: '' + action: /status/completions + consequence: + - Open +- name: Back + description: '' + action: / + consequence: + - Back diff --git a/runs/permits-2026-09-25/fixed/questions/received/exemption-request.yaml b/runs/permits-2026-09-25/fixed/questions/received/exemption-request.yaml new file mode 100644 index 0000000..04c3fe3 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/received/exemption-request.yaml @@ -0,0 +1,15 @@ +name: What happens now? +description: It has reached our case officers. +alternatives: +- name: We read it and come back to you + description: Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example. +- name: See all exemptions + description: '' + action: /status/exemptions + consequence: + - Open +- name: Back + description: '' + action: / + consequence: + - Back diff --git a/runs/permits-2026-09-25/fixed/questions/received/firm-approval.yaml b/runs/permits-2026-09-25/fixed/questions/received/firm-approval.yaml new file mode 100644 index 0000000..71486fa --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/received/firm-approval.yaml @@ -0,0 +1,10 @@ +name: What happens now? +description: It has reached our case officers. +alternatives: +- name: We read it and come back to you + description: Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example. +- name: Back + description: '' + action: / + consequence: + - Back diff --git a/runs/permits-2026-09-25/fixed/questions/received/illegal-building-report.yaml b/runs/permits-2026-09-25/fixed/questions/received/illegal-building-report.yaml new file mode 100644 index 0000000..1dad0c2 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/received/illegal-building-report.yaml @@ -0,0 +1,10 @@ +name: What happens now? +description: It has reached our inspectors. +alternatives: +- name: We read it and come back to you + description: Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example. +- name: Back + description: '' + action: / + consequence: + - Back diff --git a/runs/permits-2026-09-25/fixed/questions/received/objection.yaml b/runs/permits-2026-09-25/fixed/questions/received/objection.yaml new file mode 100644 index 0000000..c75f760 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/received/objection.yaml @@ -0,0 +1,15 @@ +name: What happens now? +description: It has reached our case officers. +alternatives: +- name: We read it and come back to you + description: Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example. +- name: See all objections + description: '' + action: /status/objections + consequence: + - Open +- name: Back + description: '' + action: / + consequence: + - Back diff --git a/runs/permits-2026-09-25/fixed/questions/received/pre-application-meeting.yaml b/runs/permits-2026-09-25/fixed/questions/received/pre-application-meeting.yaml new file mode 100644 index 0000000..71486fa --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/received/pre-application-meeting.yaml @@ -0,0 +1,10 @@ +name: What happens now? +description: It has reached our case officers. +alternatives: +- name: We read it and come back to you + description: Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example. +- name: Back + description: '' + action: / + consequence: + - Back diff --git a/runs/permits-2026-09-25/fixed/questions/received/small-works-application.yaml b/runs/permits-2026-09-25/fixed/questions/received/small-works-application.yaml new file mode 100644 index 0000000..6e621eb --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/received/small-works-application.yaml @@ -0,0 +1,15 @@ +name: What happens now? +description: It has reached our case officers. +alternatives: +- name: We read it and come back to you + description: Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example. +- name: See all applications + description: '' + action: /status/applications + consequence: + - Open +- name: Back + description: '' + action: / + consequence: + - Back diff --git a/runs/permits-2026-09-25/fixed/questions/section_head/_section.yaml b/runs/permits-2026-09-25/fixed/questions/section_head/_section.yaml new file mode 100644 index 0000000..569137f --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/section_head/_section.yaml @@ -0,0 +1 @@ +qualifies: section_head diff --git a/runs/permits-2026-09-25/fixed/questions/section_head/index.yaml b/runs/permits-2026-09-25/fixed/questions/section_head/index.yaml new file mode 100644 index 0000000..c8b9474 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/section_head/index.yaml @@ -0,0 +1,356 @@ +name: What needs doing? +description: Everything head of section looks after. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: Appeals + description: Sent in by anyone with an interest who will not accept a decision of ours. + action: /section_head + consequence: + - Confirm + features: + - name: Appeals + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: appeals + requires_group: section_head + transitions: + - from: before_the_board + to: changed_by_us + label: We changed our own decision + - from: reconsidered + to: before_the_board + label: With the appeals board +- name: Applications + description: Sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner. + action: /section_head + consequence: + - Confirm + features: + - name: Applications + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: applications + requires_group: section_head + transitions: + - from: complete + to: refused + label: Refused + - from: incomplete + to: refused + label: Refused + - from: on_hearing + to: refused + label: Refused + - from: open + to: refused + label: Refused + - from: recommended + to: approved + label: Approved + - from: recommended + to: approved_with_conditions + label: Approved on conditions + - from: recommended + to: refused + label: Refused +- name: Completions + description: Sent in by an owner or firm whose building work is finished. + action: /section_head + consequence: + - Confirm + features: + - name: Completions + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: completions + requires_group: section_head + transitions: + - from: checked + to: temporary_permission + label: Temporary permission to use + - from: checked + to: certificate_issued + label: Certificate issued + - from: checked + to: refused + label: Refused + - from: open + to: refused + label: Refused + - from: temporary_permission + to: certificate_issued + label: Certificate issued +- name: Exemptions + description: Sent in by someone whose plans break a rule in the zoning map. + action: /section_head + consequence: + - Confirm + features: + - name: Exemptions + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: exemptions + requires_group: section_head + transitions: + - from: county_answered + to: denied + label: Denied + - from: county_asked + to: denied + label: Denied + - from: open + to: denied + label: Denied + - from: recommended + to: granted + label: Granted + - from: recommended + to: denied + label: Denied +- name: Firms + description: Sent in by an architect or engineering firm that files for its clients. + action: /section_head + consequence: + - Confirm + features: + - name: Firms + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: firms + requires_group: section_head + transitions: + - from: checked + to: approved + label: Approved + - from: checked + to: declined + label: Declined + - from: open + to: declined + label: Declined + - from: papers_missing + to: declined + label: Declined +- name: Hearing answers + description: Sent in by a road, fire, heritage or county officer who has been asked about a case. + action: /section_head + consequence: + - Confirm + features: + - name: Hearing answers + description: Each row is one case and the stage it has reached. Another desk moves these. + resource: + source: + kind: kv + bucket: hearing_answers + requires_group: section_head + transitions: [] +- name: Hearings + description: Sent in by a case officer sending a case out to the authority that must see it. + action: /section_head + consequence: + - Confirm + features: + - name: Hearings + description: Each row is one case and the stage it has reached. Another desk moves these. + resource: + source: + kind: kv + bucket: hearings + requires_group: section_head + transitions: [] +- name: Illegal building + description: Sent in by someone who can see building going up that nobody was told about. + action: /section_head + consequence: + - Confirm + features: + - name: Illegal building + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: illegal_building + requires_group: section_head + transitions: + - from: inspected + to: fined + label: Fined + - from: open + to: fined + label: Fined +- name: Inspections + description: Sent in by an inspector on a scaffold with gloves on and the wind blowing. + action: /section_head + consequence: + - Confirm + features: + - name: Inspections + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: inspections + requires_group: section_head + transitions: + - from: deviation + to: escalated + label: Handed to a case officer + - from: open + to: escalated + label: Handed to a case officer +- name: Objections + description: Sent in by a neighbour who got a notice about what is planned next door. + action: /section_head + consequence: + - Confirm + features: + - name: Objections + description: Each row is one case and the stage it has reached. Another desk moves these. + resource: + source: + kind: kv + bucket: objections + requires_group: section_head + transitions: [] +- name: Invite someone into Hearing bodies + description: They get an account, a place in Hearing bodies, and a one-time link to set their own password or passkey. + action: /section_head + consequence: + - Invite + invite: + group: agencies + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invite someone into Appeals board + description: They get an account, a place in Appeals board, and a one-time link to set their own password or passkey. + action: /section_head + consequence: + - Invite + invite: + group: appeals_board + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invite someone into Approved firms + description: They get an account, a place in Approved firms, and a one-time link to set their own password or passkey. + action: /section_head + consequence: + - Invite + invite: + group: approved_firms + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invite someone into Case officers + description: They get an account, a place in Case officers, and a one-time link to set their own password or passkey. + action: /section_head + consequence: + - Invite + invite: + group: case_officers + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invite someone into Front desk + description: They get an account, a place in Front desk, and a one-time link to set their own password or passkey. + action: /section_head + consequence: + - Invite + invite: + group: front_desk + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invite someone into Inspectors + description: They get an account, a place in Inspectors, and a one-time link to set their own password or passkey. + action: /section_head + consequence: + - Invite + invite: + group: inspectors + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invite someone into Head of section + description: They get an account, a place in Head of section, and a one-time link to set their own password or passkey. + action: /section_head + consequence: + - Invite + invite: + group: section_head + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invitations sent + description: Each invite with the link it made. Mark it done when the person is in. + action: /section_head + consequence: + - Confirm + features: + - name: Who has been invited + description: Each row is one invitation, with the one-time link while it is unused. + resource: + source: + kind: kv + bucket: portal_invites + requires_group: section_head + transitions: + - from: open + to: done + label: Is in diff --git a/runs/permits-2026-09-25/fixed/questions/status/appeals/index.yaml b/runs/permits-2026-09-25/fixed/questions/status/appeals/index.yaml new file mode 100644 index 0000000..662ae18 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/status/appeals/index.yaml @@ -0,0 +1,22 @@ +name: What has been sent in about appeals? +description: Everything sent in by anyone with an interest who will not accept a decision of ours, and where each one stands. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: Appeals + description: '' + features: + - name: Appeals + description: Each row is one case and the stage it has reached. Names and contact details are not shown here. + resource: + source: + kind: kv + bucket: appeals + public: true + jq: '.[] | .responses |= {case_number: .case_number, property: .property, what_you_disagree_with: .what_you_disagree_with, your_interest: .your_interest}' +- name: Back + description: '' + action: / + consequence: + - Back diff --git a/runs/permits-2026-09-25/fixed/questions/status/applications/index.yaml b/runs/permits-2026-09-25/fixed/questions/status/applications/index.yaml new file mode 100644 index 0000000..3146555 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/status/applications/index.yaml @@ -0,0 +1,22 @@ +name: What has been sent in about applications? +description: Everything sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner, and where each one stands. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: Applications + description: '' + features: + - name: Applications + description: Each row is one case and the stage it has reached. Names and contact details are not shown here. + resource: + source: + kind: kv + bucket: applications + public: true + jq: '.[] | .responses |= {drawings_url: .drawings_url, neighbours_notified: .neighbours_notified, property_address: .property_address, property_number: .property_number, site: .site, what_is_planned: .what_is_planned}' +- name: Back + description: '' + action: / + consequence: + - Back diff --git a/runs/permits-2026-09-25/fixed/questions/status/completions/index.yaml b/runs/permits-2026-09-25/fixed/questions/status/completions/index.yaml new file mode 100644 index 0000000..c635e35 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/status/completions/index.yaml @@ -0,0 +1,22 @@ +name: What has been sent in about completions? +description: Everything sent in by an owner or firm whose building work is finished, and where each one stands. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: Completions + description: '' + features: + - name: Completions + description: Each row is one case and the stage it has reached. Names and contact details are not shown here. + resource: + source: + kind: kv + bucket: completions + public: true + jq: '.[] | .responses |= {asking_for: .asking_for, case_number: .case_number, property_address: .property_address, what_is_outstanding: .what_is_outstanding, work_finished: .work_finished}' +- name: Back + description: '' + action: / + consequence: + - Back diff --git a/runs/permits-2026-09-25/fixed/questions/status/exemptions/index.yaml b/runs/permits-2026-09-25/fixed/questions/status/exemptions/index.yaml new file mode 100644 index 0000000..7bc890c --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/status/exemptions/index.yaml @@ -0,0 +1,22 @@ +name: What has been sent in about exemptions? +description: Everything sent in by someone whose plans break a rule in the zoning map, and where each one stands. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: Exemptions + description: '' + features: + - name: Exemptions + description: Each row is one case and the stage it has reached. Names and contact details are not shown here. + resource: + source: + kind: kv + bucket: exemptions + public: true + jq: '.[] | .responses |= {case_number: .case_number, site: .site, which_rule: .which_rule, why_it_should_be_allowed: .why_it_should_be_allowed}' +- name: Back + description: '' + action: / + consequence: + - Back diff --git a/runs/permits-2026-09-25/fixed/questions/status/objections/index.yaml b/runs/permits-2026-09-25/fixed/questions/status/objections/index.yaml new file mode 100644 index 0000000..416efb6 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/status/objections/index.yaml @@ -0,0 +1,22 @@ +name: What has been sent in about objections? +description: Everything sent in by a neighbour who got a notice about what is planned next door, and where each one stands. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: Objections + description: '' + features: + - name: Objections + description: Each row is one case and the stage it has reached. Names and contact details are not shown here. + resource: + source: + kind: kv + bucket: objections + public: true + jq: '.[] | .responses |= {case_number: .case_number, your_objection: .your_objection, your_property: .your_property}' +- name: Back + description: '' + action: / + consequence: + - Back diff --git a/runs/permits-2026-09-25/fixed/questions/want-to-build/index.yaml b/runs/permits-2026-09-25/fixed/questions/want-to-build/index.yaml new file mode 100644 index 0000000..4b3e350 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/questions/want-to-build/index.yaml @@ -0,0 +1,156 @@ +name: What do you need? +description: For an owner or a firm with something to build, divide or change. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: to hear what we will allow before paying an architect + description: For someone with an idea for a building and no drawings yet. + action: /received/pre-application-meeting + consequence: + - Send + record_as: meetings + features: + - name: What happens next + description: It is open, then scheduled, then we have met, and ends written advice sent or cancelled. + icon: lucide:route + - name: Who reads it + description: Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example. + icon: lucide:users + - name: Details + requirements: + - name: name + label: Name + type: text + - name: email + label: Email + type: email + - name: property_address + label: Property address + type: text + - name: what_you_want + label: What you want + type: textarea + - name: phone + label: Phone + type: tel + optional: true + - name: site + label: Site + type: location + optional: true +- name: permission to build it, and to know where the case stands + description: For an owner applying for something small enough to file themselves. + action: /received/small-works-application + consequence: + - Send + record_as: applications + features: + - name: What happens next + description: It is open, then papers missing, then papers complete, then out to the neighbours and the agencies, then recommendation written, and ends approved, approved on conditions, refused or withdrawn. + icon: lucide:route + - name: Who reads it + description: Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example. + icon: lucide:users + - name: Details + requirements: + - name: email + label: Email + type: email + - name: property_address + label: Property address + type: text + - name: property_number + label: Property number + type: text + - name: what_is_planned + label: What is planned + type: textarea + - name: neighbours_notified + label: Neighbours notified + type: select + options: + - Yes + - Not yet + - name: site + label: Site + type: location + optional: true + - name: drawings_url + label: Drawings url + type: text + optional: true +- name: to be allowed it anyway, with reasons on the record + description: For someone whose plans break a rule in the zoning map. + action: /received/exemption-request + consequence: + - Send + record_as: exemptions + features: + - name: What you need + description: An application already with us, and the case number from its receipt. + icon: lucide:key + - name: What happens next + description: It is open, then with the county, then the county has answered, then recommended, and ends granted, denied or withdrawn. + icon: lucide:route + - name: Who reads it + description: Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example. + icon: lucide:users + - name: Details + requirements: + - name: email + label: Email + type: email + - name: case_number + label: Case number + type: text + - name: which_rule + label: Which rule + type: text + - name: why_it_should_be_allowed + label: Why it should be allowed + type: textarea + - name: site + label: Site + type: location + optional: true +- name: the certificate that lets the building be used + description: For an owner or firm whose building work is finished. + action: /received/completion-request + consequence: + - Send + record_as: completions + features: + - name: What you need + description: A case number, and the work finished or close enough to move in. + icon: lucide:key + - name: What happens next + description: It is open, then checked against the inspections, then temporary permission to use, and ends certificate issued or refused. + icon: lucide:route + - name: Who reads it + description: Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example. + icon: lucide:users + - name: Details + requirements: + - name: email + label: Email + type: email + - name: case_number + label: Case number + type: text + - name: property_address + label: Property address + type: text + - name: work_finished + label: Work finished + type: date + - name: asking_for + label: Asking for + type: select + options: + - Completion certificate + - Temporary permission to move in + - name: what_is_outstanding + label: What is outstanding + type: textarea + optional: true diff --git a/runs/permits-2026-09-25/fixed/site.yaml b/runs/permits-2026-09-25/fixed/site.yaml new file mode 100644 index 0000000..9d30842 --- /dev/null +++ b/runs/permits-2026-09-25/fixed/site.yaml @@ -0,0 +1,5 @@ +title: Vestmark kommune - Building and Planning +lang: en +mail: + from: Vestmark Building and Planning + reply_to: byggesak@vestmark.example diff --git a/runs/permits-2026-09-25/needs.yaml b/runs/permits-2026-09-25/needs.yaml new file mode 100644 index 0000000..e8fc8a7 --- /dev/null +++ b/runs/permits-2026-09-25/needs.yaml @@ -0,0 +1,499 @@ +needs: +- id: pre-application-meeting + who: someone with an idea for a building and no drawings yet + wants: to hear what we will allow before paying an architect + enters: / + via: Want to build + lands_in: meetings + handled_by: case_officers + stages: + - open + - scheduled + - met + - advised + - cancelled + done_when: + - advised + - cancelled + success: + - advised + max_steps: 2 + max_fields: 5 + stage_words: + open: open + scheduled: scheduled + met: we have met + advised: written advice sent + cancelled: cancelled + also_moved_by: + - front_desk +- id: small-works-application + who: an owner applying for something small enough to file themselves + wants: permission to build it, and to know where the case stands + enters: / + via: Want to build + lands_in: applications + handled_by: case_officers + stages: + - open + - incomplete + - complete + - on_hearing + - recommended + - approved + - approved_with_conditions + - refused + - withdrawn + done_when: + - approved + - approved_with_conditions + - refused + - withdrawn + success: + - approved + - approved_with_conditions + max_steps: 2 + max_fields: 6 + stage_words: + open: open + incomplete: papers missing + complete: papers complete + on_hearing: out to the neighbours and the agencies + recommended: recommendation written + approved: approved + approved_with_conditions: approved on conditions + refused: refused + withdrawn: withdrawn + also_moved_by: + - section_head +- id: exemption-request + who: someone whose plans break a rule in the zoning map + wants: to be allowed it anyway, with reasons on the record + enters: / + via: Want to build + lands_in: exemptions + handled_by: case_officers + stages: + - open + - county_asked + - county_answered + - recommended + - granted + - denied + - withdrawn + done_when: + - granted + - denied + - withdrawn + success: + - granted + max_steps: 2 + max_fields: 4 + stage_words: + open: open + county_asked: with the county + county_answered: the county has answered + recommended: recommended + granted: granted + denied: denied + withdrawn: withdrawn + also_moved_by: + - agencies + - section_head +- id: completion-request + who: an owner or firm whose building work is finished + wants: the certificate that lets the building be used + enters: / + via: Want to build + lands_in: completions + handled_by: case_officers + stages: + - open + - checked + - temporary_permission + - certificate_issued + - refused + done_when: + - certificate_issued + - refused + success: + - certificate_issued + max_steps: 2 + max_fields: 5 + stage_words: + open: open + checked: checked against the inspections + temporary_permission: temporary permission to use + certificate_issued: certificate issued + refused: refused + also_moved_by: + - section_head +- id: objection + who: a neighbour who got a notice about what is planned next door + wants: what they think on the record, and answered in the decision + enters: / + via: Building near me + lands_in: objections + handled_by: case_officers + stages: + - open + - registered + - answered_by_applicant + - addressed + - withdrawn + done_when: + - addressed + - withdrawn + success: + - addressed + max_steps: 2 + max_fields: 4 + stage_words: + open: open + registered: on the case file + answered_by_applicant: the applicant has answered + addressed: answered in the decision + withdrawn: withdrawn + also_moved_by: + - approved_firms +- id: case-status-enquiry + who: someone waiting on a case and getting nothing back + wants: to be told where it actually stands + enters: / + via: Building near me + lands_in: enquiries + handled_by: front_desk + stages: + - open + - in_hand + - answered + done_when: + - answered + success: + - answered + max_steps: 2 + max_fields: 3 + stage_words: + open: open + in_hand: in hand + answered: answered + also_moved_by: + - case_officers +- id: illegal-building-report + who: someone who can see building going up that nobody was told about + wants: us to go and look, and to hear that we did + enters: / + via: Building near me + lands_in: illegal_building + handled_by: inspectors + stages: + - open + - inspected + - owner_asked + - explained + - resolved + - fined + - dropped + done_when: + - resolved + - fined + - dropped + success: + - resolved + - dropped + max_steps: 2 + max_fields: 3 + stage_words: + open: open + inspected: inspected + owner_asked: the owner has been written to + explained: the owner has answered + resolved: resolved + fined: fined + dropped: nothing to pursue + also_moved_by: + - case_officers + - section_head +- id: appeal + who: anyone with an interest who will not accept a decision of ours + wants: the decision looked at again, by us and then by the board + enters: / + via: the decision looked at again, by us and then by the board + lands_in: appeals + handled_by: case_officers + stages: + - open + - reconsidered + - changed_by_us + - before_the_board + - upheld + - overturned + - withdrawn + done_when: + - changed_by_us + - upheld + - overturned + - withdrawn + success: + - changed_by_us + - upheld + max_steps: 1 + max_fields: 5 + stage_words: + open: open + reconsidered: we are looking at it again + changed_by_us: we changed our own decision + before_the_board: with the appeals board + upheld: the board kept our decision + overturned: the board overturned us + withdrawn: withdrawn + also_moved_by: + - appeals_board + - section_head +- id: firm-approval + who: an architect or engineering firm that files for its clients + wants: to be on the list, and then to file without asking again + enters: / + via: to be on the list, and then to file without asking again + lands_in: firms + handled_by: case_officers + stages: + - open + - papers_missing + - checked + - approved + - declined + done_when: + - approved + - declined + success: + - approved + max_steps: 1 + max_fields: 6 + stage_words: + open: open + papers_missing: waiting on papers + checked: papers checked + approved: approved + declined: declined + also_moved_by: + - section_head +- id: permit-application + who: an approved firm filing on behalf of an owner + wants: a decision inside twelve weeks, and to know when the clock stops + enters: /approved_firms/permit-application + via: a decision inside twelve weeks, and to know when the clock stops + lands_in: applications + handled_by: case_officers + stages: + - open + - incomplete + - complete + - on_hearing + - recommended + - approved + - approved_with_conditions + - refused + - withdrawn + done_when: + - approved + - approved_with_conditions + - refused + - withdrawn + success: + - approved + - approved_with_conditions + max_steps: 1 + max_fields: 6 + stage_words: + open: open + incomplete: papers missing + complete: papers complete + on_hearing: out to the neighbours and the agencies + recommended: recommendation written + approved: approved + approved_with_conditions: approved on conditions + refused: refused + withdrawn: withdrawn + enters_as: approved_firms + also_moved_by: + - section_head +- id: log-counter-enquiry + who: whoever is on the counter with a queue and a caller on the line + wants: the question written down and sent to whoever has the case + enters: /front_desk/log-counter-enquiry + via: the question written down and sent to whoever has the case + lands_in: enquiries + handled_by: front_desk + stages: + - open + - in_hand + - answered + done_when: + - answered + success: + - answered + max_steps: 1 + max_fields: 3 + stage_words: + open: open + in_hand: in hand + answered: answered + enters_as: front_desk + also_moved_by: + - case_officers +- id: request-hearing + who: a case officer sending a case out to the authority that must see it + wants: an answer by the deadline, or a record that none came + enters: /case_officers/request-hearing + via: an answer by the deadline, or a record that none came + lands_in: hearings + handled_by: case_officers + stages: + - open + - answered + - no_answer + - cancelled + done_when: + - answered + - no_answer + - cancelled + success: + - answered + max_steps: 1 + max_fields: 4 + stage_words: + open: open + answered: answered + no_answer: the deadline passed with no answer + cancelled: cancelled + enters_as: case_officers + also_moved_by: + - agencies +- id: hearing-answer + who: a road, fire, heritage or county officer who has been asked about a case + wants: their answer on the file, in their own words + enters: /agencies/hearing-answer + via: their answer on the file, in their own words + lands_in: hearing_answers + handled_by: case_officers + stages: + - open + - read + - followed + - set_aside + done_when: + - followed + - set_aside + success: + - followed + max_steps: 1 + max_fields: 4 + stage_words: + open: open + read: read by the case officer + followed: followed in the decision + set_aside: set aside with reasons + enters_as: agencies +- id: inspection-finding + who: an inspector on a scaffold with gloves on and the wind blowing + wants: what they found logged before they climb down + enters: /inspectors/inspection-finding + via: what they found logged before they climb down + lands_in: inspections + handled_by: inspectors + stages: + - open + - as_approved + - deviation + - put_right + - escalated + done_when: + - as_approved + - put_right + - escalated + success: + - as_approved + - put_right + max_steps: 1 + max_fields: 3 + stage_words: + open: open + as_approved: built as approved + deviation: built differently + put_right: put right + escalated: handed to a case officer + enters_as: inspectors + also_moved_by: + - case_officers + - section_head +personas: +- id: garage-owner + need: pre-application-meeting + text: We want to put a double garage where the old shed is. Before I pay an architect I'd like to know whether you'll even allow it, because the neighbour says it's too close to the road. +- id: shop-to-flats + need: pre-application-meeting + text: I own the old grocery on Torget and want to make four flats out of it. There are a lot of questions - parking, fire, the facade is listed. Can we sit down with someone? +- id: firm-files-extension + need: permit-application + text: We are the responsible applicant for an extension at Bjorkeveien 14. Drawings, site plan and the neighbour notices are all ready. We file maybe forty of these a year. +- id: owner-small-window + need: permit-application + text: I want to put a dormer window in my roof. The man at the counter said I have to apply even though it's small. +- id: missing-drawings + need: permit-application + text: You wrote that our section drawing is missing and the case is on hold. I've got it here now, where do I send it so the clock starts again? +- id: too-close-to-boundary + need: exemption-request + text: The garage ends up one and a half metres from the boundary and the plan says four. We are asking you to allow it anyway - the ground falls away steeply everywhere else on the plot. +- id: neighbour-view + need: objection + text: I got a notice about the extension at number 14. It takes the afternoon sun off my entire terrace and I want that on the record before you decide anything. +- id: neighbour-parking + need: objection + text: The flats they want to build in the old grocery have four parking places for four flats and everyone here already parks on the street. I object. +- id: road-authority + need: hearing-answer + text: 'Regarding your case 2026/418: the access onto the county road is within the sight line and we cannot accept it as drawn. Our formal reply is attached.' +- id: fire-service + need: hearing-answer + text: We have looked at the conversion on Torget. We have no objection provided the stairwell is upgraded. Reference your case 2026/501. +- id: refused-applicant + need: appeal + text: You refused our exemption on the ninth. We don't accept the reasoning - you've allowed the same thing twice in the same street. We're appealing. +- id: neighbour-appeals + need: appeal + text: You approved the extension next door even though I objected. I'm appealing the decision. What do I need to send? +- id: board-member + need: appeal + text: I sit on the appeals board. I need the case, our own decision, and what the neighbours wrote, before Tuesday. +- id: inspector-on-roof + need: inspection-finding + text: I'm up on the scaffold at Bjorkeveien. The fire wall isn't built to the drawing at all. I've got gloves on and it's blowing. I want this logged before I climb down. +- id: inspector-all-good + need: inspection-finding + text: Been out at Torget. Everything is as approved. Nothing to report but I have to record that I was there. +- id: firm-wants-certificate + need: completion-request + text: The work at Bjorkeveien 14 is finished and inspected. We're asking for the completion certificate so the owners can get their mortgage released. +- id: wants-to-move-in + need: completion-request + text: The house is done apart from the outside steps, which we can't pour until spring. The family has sold their flat. Can we get a temporary permission to move in? +- id: something-behind-fence + need: illegal-building-report + text: There's a large structure going up behind the fence at Solbakken 7. Nobody has had a notice about it and it's been going on for two weeks. +- id: owner-explains + need: illegal-building-report + text: I got your letter about the terrace. I genuinely did not know it needed an application, it's been there since we moved in. What happens now? +- id: new-firm + need: firm-approval + text: We are a three-person architecture firm that has just started. We want to be approved so we can file applications for our clients in your municipality. +- id: firm-insurance-lapsed + need: firm-approval + text: You wrote that our liability insurance certificate has expired. We have renewed it, here it is. +- id: counter-phone-call + need: log-counter-enquiry + text: A woman rang about the case behind her house. Wants to know where it stands. I'm at the counter and there's a queue - I need to write it down and send it to whoever has that case. +- id: where-is-my-case + need: case-status-enquiry + text: I sent in my application five weeks ago and I've heard nothing. Is anyone looking at it? Is it in the six weeks with the neighbours or is it waiting on me? diff --git a/runs/permits-2026-09-25/questions/agencies/_section.yaml b/runs/permits-2026-09-25/questions/agencies/_section.yaml new file mode 100644 index 0000000..71cfb91 --- /dev/null +++ b/runs/permits-2026-09-25/questions/agencies/_section.yaml @@ -0,0 +1 @@ +qualifies: agencies diff --git a/runs/permits-2026-09-25/questions/agencies/hearing-answer-sent.yaml b/runs/permits-2026-09-25/questions/agencies/hearing-answer-sent.yaml new file mode 100644 index 0000000..8bc747e --- /dev/null +++ b/runs/permits-2026-09-25/questions/agencies/hearing-answer-sent.yaml @@ -0,0 +1,10 @@ +name: What happens now? +description: It has reached our case officers. +alternatives: +- name: We read it and come back to you + description: Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example. +- name: Back + description: '' + action: /agencies + consequence: + - Back diff --git a/runs/permits-2026-09-25/questions/agencies/hearing-answer.yaml b/runs/permits-2026-09-25/questions/agencies/hearing-answer.yaml new file mode 100644 index 0000000..23c7b7e --- /dev/null +++ b/runs/permits-2026-09-25/questions/agencies/hearing-answer.yaml @@ -0,0 +1,46 @@ +followup: false +name: Hearing answer? +description: '' +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: their answer on the file, in their own words + description: For a road, fire, heritage or county officer who has been asked about a case. + action: /agencies/hearing-answer-sent + consequence: + - Send + record_as: hearing_answers + features: + - name: What you need + description: The hearing letter we sent you, which has the case number on it. + icon: lucide:key + - name: What happens next + description: It is open, then read by the case officer, and ends followed in the decision or set aside with reasons. + icon: lucide:route + - name: Who reads it + description: Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example. + icon: lucide:users + - name: Details + requirements: + - name: case_number + label: Case number + type: text + - name: which_authority + label: Which authority + type: select + options: + - Road authority + - Fire service + - Heritage office + - The county + - name: our_answer + label: Our answer + type: select + options: + - No objection + - Objection + - Conditions required + - name: what_we_say + label: What we say + type: textarea diff --git a/runs/permits-2026-09-25/questions/agencies/index.yaml b/runs/permits-2026-09-25/questions/agencies/index.yaml new file mode 100644 index 0000000..485074a --- /dev/null +++ b/runs/permits-2026-09-25/questions/agencies/index.yaml @@ -0,0 +1,78 @@ +name: What needs doing? +description: Everything hearing bodies looks after. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: Exemptions + description: Sent in by someone whose plans break a rule in the zoning map. + action: /agencies + consequence: + - Confirm + features: + - name: Exemptions + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: exemptions + requires_group: agencies + transitions: + - from: county_asked + to: county_answered + label: The county has answered +- name: Hearings + description: Sent in by a case officer sending a case out to the authority that must see it. + action: /agencies + consequence: + - Confirm + features: + - name: Hearings + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: hearings + requires_group: agencies + transitions: + - from: open + to: answered + label: Answered +- name: their answer on the file, in their own words + description: For a road, fire, heritage or county officer who has been asked about a case. + action: /agencies/hearing-answer + consequence: + - Open +- name: Invite someone into Hearing bodies + description: They get an account, a place in Hearing bodies, and a one-time link to set their own password or passkey. + action: /agencies + consequence: + - Invite + invite: + group: agencies + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invitations sent + description: Each invite with the link it made. Mark it done when the person is in. + action: /agencies + consequence: + - Confirm + features: + - name: Who has been invited + description: Each row is one invitation, with the one-time link while it is unused. + resource: + source: + kind: kv + bucket: portal_invites + requires_group: agencies + transitions: + - from: open + to: done + label: Is in diff --git a/runs/permits-2026-09-25/questions/appeals_board/_section.yaml b/runs/permits-2026-09-25/questions/appeals_board/_section.yaml new file mode 100644 index 0000000..a23502c --- /dev/null +++ b/runs/permits-2026-09-25/questions/appeals_board/_section.yaml @@ -0,0 +1 @@ +qualifies: appeals_board diff --git a/runs/permits-2026-09-25/questions/appeals_board/index.yaml b/runs/permits-2026-09-25/questions/appeals_board/index.yaml new file mode 100644 index 0000000..fb84700 --- /dev/null +++ b/runs/permits-2026-09-25/questions/appeals_board/index.yaml @@ -0,0 +1,59 @@ +name: What needs doing? +description: Everything appeals board looks after. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: Appeals + description: Sent in by anyone with an interest who will not accept a decision of ours. + action: /appeals_board + consequence: + - Confirm + features: + - name: Appeals + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: appeals + requires_group: appeals_board + transitions: + - from: before_the_board + to: overturned + label: The board overturned us + - from: before_the_board + to: upheld + label: The board kept our decision +- name: Invite someone into Appeals board + description: They get an account, a place in Appeals board, and a one-time link to set their own password or passkey. + action: /appeals_board + consequence: + - Invite + invite: + group: appeals_board + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invitations sent + description: Each invite with the link it made. Mark it done when the person is in. + action: /appeals_board + consequence: + - Confirm + features: + - name: Who has been invited + description: Each row is one invitation, with the one-time link while it is unused. + resource: + source: + kind: kv + bucket: portal_invites + requires_group: appeals_board + transitions: + - from: open + to: done + label: Is in diff --git a/runs/permits-2026-09-25/questions/approved_firms/_section.yaml b/runs/permits-2026-09-25/questions/approved_firms/_section.yaml new file mode 100644 index 0000000..85f1f10 --- /dev/null +++ b/runs/permits-2026-09-25/questions/approved_firms/_section.yaml @@ -0,0 +1 @@ +qualifies: approved_firms diff --git a/runs/permits-2026-09-25/questions/approved_firms/index.yaml b/runs/permits-2026-09-25/questions/approved_firms/index.yaml new file mode 100644 index 0000000..bc823e4 --- /dev/null +++ b/runs/permits-2026-09-25/questions/approved_firms/index.yaml @@ -0,0 +1,61 @@ +name: What needs doing? +description: Everything approved firms looks after. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: Objections + description: Sent in by a neighbour who got a notice about what is planned next door. + action: /approved_firms + consequence: + - Confirm + features: + - name: Objections + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: objections + requires_group: approved_firms + transitions: + - from: registered + to: answered_by_applicant + label: The applicant has answered +- name: a decision inside twelve weeks, and to know when the clock stops + description: For an approved firm filing on behalf of an owner. + action: /approved_firms/permit-application + consequence: + - Open +- name: Invite someone into Approved firms + description: They get an account, a place in Approved firms, and a one-time link to set their own password or passkey. + action: /approved_firms + consequence: + - Invite + invite: + group: approved_firms + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invitations sent + description: Each invite with the link it made. Mark it done when the person is in. + action: /approved_firms + consequence: + - Confirm + features: + - name: Who has been invited + description: Each row is one invitation, with the one-time link while it is unused. + resource: + source: + kind: kv + bucket: portal_invites + requires_group: approved_firms + transitions: + - from: open + to: done + label: Is in diff --git a/runs/permits-2026-09-25/questions/approved_firms/permit-application-sent.yaml b/runs/permits-2026-09-25/questions/approved_firms/permit-application-sent.yaml new file mode 100644 index 0000000..6914aa3 --- /dev/null +++ b/runs/permits-2026-09-25/questions/approved_firms/permit-application-sent.yaml @@ -0,0 +1,15 @@ +name: What happens now? +description: It has reached our case officers. +alternatives: +- name: We read it and come back to you + description: Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example. +- name: See all applications + description: '' + action: /status/applications + consequence: + - Open +- name: Back + description: '' + action: /approved_firms + consequence: + - Back diff --git a/runs/permits-2026-09-25/questions/approved_firms/permit-application.yaml b/runs/permits-2026-09-25/questions/approved_firms/permit-application.yaml new file mode 100644 index 0000000..50d5e38 --- /dev/null +++ b/runs/permits-2026-09-25/questions/approved_firms/permit-application.yaml @@ -0,0 +1,48 @@ +followup: false +name: Permit application? +description: '' +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: a decision inside twelve weeks, and to know when the clock stops + description: For an approved firm filing on behalf of an owner. + action: /approved_firms/permit-application-sent + consequence: + - Send + record_as: applications + features: + - name: What happens next + description: It is open, then papers missing, then papers complete, then out to the neighbours and the agencies, then recommendation written, and ends approved, approved on conditions, refused or withdrawn. + icon: lucide:route + - name: Who reads it + description: Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example. + icon: lucide:users + - name: Details + requirements: + - name: email + label: Email + type: email + - name: property_address + label: Property address + type: text + - name: property_number + label: Property number + type: text + - name: what_is_planned + label: What is planned + type: textarea + - name: neighbours_notified + label: Neighbours notified + type: select + options: + - Yes + - Not yet + - name: site + label: Site + type: location + optional: true + - name: drawings_url + label: Drawings url + type: text + optional: true diff --git a/runs/permits-2026-09-25/questions/building-near-me/index.yaml b/runs/permits-2026-09-25/questions/building-near-me/index.yaml new file mode 100644 index 0000000..caf6e50 --- /dev/null +++ b/runs/permits-2026-09-25/questions/building-near-me/index.yaml @@ -0,0 +1,88 @@ +name: What do you need? +description: For someone who lives next to what is being built. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: what they think on the record, and answered in the decision + description: For a neighbour who got a notice about what is planned next door. + action: /received/objection + consequence: + - Send + record_as: objections + features: + - name: What you need + description: The notice that came in the post, which has the case number on it. + icon: lucide:key + - name: What happens next + description: It is open, then on the case file, then the applicant has answered, and ends answered in the decision or withdrawn. + icon: lucide:route + - name: Who reads it + description: Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example. + icon: lucide:users + - name: Details + requirements: + - name: email + label: Email + type: email + - name: case_number + label: Case number + type: text + - name: your_property + label: Your property + type: text + - name: your_objection + label: Your objection + type: textarea +- name: to be told where it actually stands + description: For someone waiting on a case and getting nothing back. + action: /received/case-status-enquiry + consequence: + - Send + record_as: enquiries + features: + - name: What happens next + description: It is open, then in hand, and ends answered. + icon: lucide:route + - name: Who reads it + description: Front desk. Questions go to Solveig Hauge at byggesak@vestmark.example. + icon: lucide:users + - name: Details + requirements: + - name: email + label: Email + type: email + - name: case_number_or_address + label: Case number or address + type: text + - name: what_you_want_to_know + label: What you want to know + type: textarea +- name: us to go and look, and to hear that we did + description: For someone who can see building going up that nobody was told about. + action: /received/illegal-building-report + consequence: + - Send + record_as: illegal_building + features: + - name: What happens next + description: It is open, then inspected, then the owner has been written to, then the owner has answered, and ends resolved, fined or nothing to pursue. + icon: lucide:route + - name: Who reads it + description: Inspectors. Questions go to Solveig Hauge at byggesak@vestmark.example. + icon: lucide:users + - name: Details + requirements: + - name: email + label: Email + type: email + - name: address + label: Address + type: text + - name: what_you_saw + label: What you saw + type: textarea + - name: where + label: Where + type: location + optional: true diff --git a/runs/permits-2026-09-25/questions/case_officers/_section.yaml b/runs/permits-2026-09-25/questions/case_officers/_section.yaml new file mode 100644 index 0000000..0eb3949 --- /dev/null +++ b/runs/permits-2026-09-25/questions/case_officers/_section.yaml @@ -0,0 +1 @@ +qualifies: case_officers diff --git a/runs/permits-2026-09-25/questions/case_officers/index.yaml b/runs/permits-2026-09-25/questions/case_officers/index.yaml new file mode 100644 index 0000000..d954b6c --- /dev/null +++ b/runs/permits-2026-09-25/questions/case_officers/index.yaml @@ -0,0 +1,401 @@ +name: What needs doing? +description: Everything case officers looks after. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: Appeals + description: Sent in by anyone with an interest who will not accept a decision of ours. + action: /case_officers + consequence: + - Confirm + features: + - name: Appeals + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: appeals + requires_group: case_officers + transitions: + - from: open + to: reconsidered + label: We are looking at it again +- name: Applications + description: Sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner. + action: /case_officers + consequence: + - Confirm + features: + - name: Applications + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: applications + requires_group: case_officers + transitions: + - from: complete + to: on_hearing + label: Out to the neighbours and the agencies + - from: complete + to: incomplete + label: Papers missing + - from: incomplete + to: complete + label: Papers complete + - from: on_hearing + to: recommended + label: Recommendation written + - from: on_hearing + to: incomplete + label: Papers missing + - from: open + to: complete + label: Papers complete + - from: open + to: incomplete + label: Papers missing +- name: Completions + description: Sent in by an owner or firm whose building work is finished. + action: /case_officers + consequence: + - Confirm + features: + - name: Completions + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: completions + requires_group: case_officers + transitions: + - from: open + to: checked + label: Checked against the inspections +- name: Enquiries + description: Sent in by someone waiting on a case and getting nothing back or whoever is on the counter with a queue and a caller on the line. + action: /case_officers + consequence: + - Confirm + features: + - name: Enquiries + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: enquiries + requires_group: case_officers + transitions: + - from: open + to: in_hand + label: In hand +- name: Exemptions + description: Sent in by someone whose plans break a rule in the zoning map. + action: /case_officers + consequence: + - Confirm + features: + - name: Exemptions + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: exemptions + requires_group: case_officers + transitions: + - from: county_answered + to: recommended + label: Recommended + - from: open + to: county_asked + label: With the county +- name: Firms + description: Sent in by an architect or engineering firm that files for its clients. + action: /case_officers + consequence: + - Confirm + features: + - name: Firms + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: firms + requires_group: case_officers + transitions: + - from: open + to: papers_missing + label: Waiting on papers + - from: open + to: checked + label: Papers checked + - from: papers_missing + to: checked + label: Papers checked +- name: Hearing answers + description: Sent in by a road, fire, heritage or county officer who has been asked about a case. + action: /case_officers + consequence: + - Confirm + features: + - name: Hearing answers + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: hearing_answers + requires_group: case_officers + transitions: + - from: open + to: read + label: Read by the case officer + - from: open + to: set_aside + label: Set aside with reasons + - from: read + to: followed + label: Followed in the decision + - from: read + to: set_aside + label: Set aside with reasons +- name: Hearings + description: Sent in by a case officer sending a case out to the authority that must see it. + action: /case_officers + consequence: + - Confirm + features: + - name: Hearings + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: hearings + requires_group: case_officers + transitions: + - from: open + to: no_answer + label: The deadline passed with no answer + - from: open + to: cancelled + label: Cancelled +- name: Illegal building + description: Sent in by someone who can see building going up that nobody was told about. + action: /case_officers + consequence: + - Confirm + features: + - name: Illegal building + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: illegal_building + requires_group: case_officers + transitions: + - from: inspected + to: owner_asked + label: The owner has been written to + - from: owner_asked + to: explained + label: The owner has answered +- name: Inspections + description: Sent in by an inspector on a scaffold with gloves on and the wind blowing. + action: /case_officers + consequence: + - Confirm + features: + - name: Inspections + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: inspections + requires_group: case_officers + transitions: + - from: deviation + to: escalated + label: Handed to a case officer + - from: open + to: escalated + label: Handed to a case officer +- name: Meetings + description: Sent in by someone with an idea for a building and no drawings yet. + action: /case_officers + consequence: + - Confirm + features: + - name: Meetings + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: meetings + requires_group: case_officers + transitions: + - from: met + to: advised + label: Written advice sent + - from: open + to: scheduled + label: Scheduled + - from: scheduled + to: met + label: We have met +- name: Objections + description: Sent in by a neighbour who got a notice about what is planned next door. + action: /case_officers + consequence: + - Confirm + features: + - name: Objections + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: objections + requires_group: case_officers + transitions: + - from: answered_by_applicant + to: addressed + label: Answered in the decision + - from: open + to: registered + label: On the case file + - from: registered + to: answered_by_applicant + label: The applicant has answered +- name: an answer by the deadline, or a record that none came + description: For a case officer sending a case out to the authority that must see it. + action: /case_officers/request-hearing + consequence: + - Open +- name: Invite someone into Hearing bodies + description: They get an account, a place in Hearing bodies, and a one-time link to set their own password or passkey. + action: /case_officers + consequence: + - Invite + invite: + group: agencies + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invite someone into Appeals board + description: They get an account, a place in Appeals board, and a one-time link to set their own password or passkey. + action: /case_officers + consequence: + - Invite + invite: + group: appeals_board + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invite someone into Approved firms + description: They get an account, a place in Approved firms, and a one-time link to set their own password or passkey. + action: /case_officers + consequence: + - Invite + invite: + group: approved_firms + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invite someone into Case officers + description: They get an account, a place in Case officers, and a one-time link to set their own password or passkey. + action: /case_officers + consequence: + - Invite + invite: + group: case_officers + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invite someone into Front desk + description: They get an account, a place in Front desk, and a one-time link to set their own password or passkey. + action: /case_officers + consequence: + - Invite + invite: + group: front_desk + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invite someone into Inspectors + description: They get an account, a place in Inspectors, and a one-time link to set their own password or passkey. + action: /case_officers + consequence: + - Invite + invite: + group: inspectors + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invite someone into Head of section + description: They get an account, a place in Head of section, and a one-time link to set their own password or passkey. + action: /case_officers + consequence: + - Invite + invite: + group: section_head + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invitations sent + description: Each invite with the link it made. Mark it done when the person is in. + action: /case_officers + consequence: + - Confirm + features: + - name: Who has been invited + description: Each row is one invitation, with the one-time link while it is unused. + resource: + source: + kind: kv + bucket: portal_invites + requires_group: case_officers + transitions: + - from: open + to: done + label: Is in diff --git a/runs/permits-2026-09-25/questions/case_officers/request-hearing-sent.yaml b/runs/permits-2026-09-25/questions/case_officers/request-hearing-sent.yaml new file mode 100644 index 0000000..9a588a6 --- /dev/null +++ b/runs/permits-2026-09-25/questions/case_officers/request-hearing-sent.yaml @@ -0,0 +1,10 @@ +name: What happens now? +description: It has reached our case officers. +alternatives: +- name: We read it and come back to you + description: Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example. +- name: Back + description: '' + action: /case_officers + consequence: + - Back diff --git a/runs/permits-2026-09-25/questions/case_officers/request-hearing.yaml b/runs/permits-2026-09-25/questions/case_officers/request-hearing.yaml new file mode 100644 index 0000000..7bd9196 --- /dev/null +++ b/runs/permits-2026-09-25/questions/case_officers/request-hearing.yaml @@ -0,0 +1,43 @@ +followup: false +name: Request hearing? +description: '' +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: an answer by the deadline, or a record that none came + description: For a case officer sending a case out to the authority that must see it. + action: /case_officers/request-hearing-sent + consequence: + - Send + record_as: hearings + features: + - name: What happens next + description: It is open, and ends answered, the deadline passed with no answer or cancelled. + icon: lucide:route + - name: Who reads it + description: Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example. + icon: lucide:users + - name: Details + requirements: + - name: case_number + label: Case number + type: text + - name: which_authority + label: Which authority + type: select + options: + - Road authority + - Fire service + - Heritage office + - The county + - name: what_we_ask + label: What we ask + type: textarea + - name: answer_by + label: Answer by + type: date + - name: site + label: Site + type: location + optional: true diff --git a/runs/permits-2026-09-25/questions/decide/appeal.yaml b/runs/permits-2026-09-25/questions/decide/appeal.yaml new file mode 100644 index 0000000..9b0f503 --- /dev/null +++ b/runs/permits-2026-09-25/questions/decide/appeal.yaml @@ -0,0 +1,9 @@ +name: What would you like to do? +description: '' +alternatives: +- name: Withdrawn + description: '' + self_transition: + bucket: appeals + to: withdrawn + label: Withdrawn diff --git a/runs/permits-2026-09-25/questions/decide/exemption-request.yaml b/runs/permits-2026-09-25/questions/decide/exemption-request.yaml new file mode 100644 index 0000000..647cfbc --- /dev/null +++ b/runs/permits-2026-09-25/questions/decide/exemption-request.yaml @@ -0,0 +1,9 @@ +name: What would you like to do? +description: '' +alternatives: +- name: Withdrawn + description: '' + self_transition: + bucket: exemptions + to: withdrawn + label: Withdrawn diff --git a/runs/permits-2026-09-25/questions/decide/firm-approval.yaml b/runs/permits-2026-09-25/questions/decide/firm-approval.yaml new file mode 100644 index 0000000..c858427 --- /dev/null +++ b/runs/permits-2026-09-25/questions/decide/firm-approval.yaml @@ -0,0 +1,9 @@ +name: What would you like to do? +description: '' +alternatives: +- name: Checked + description: '' + self_transition: + bucket: firms + to: checked + label: Checked diff --git a/runs/permits-2026-09-25/questions/decide/objection.yaml b/runs/permits-2026-09-25/questions/decide/objection.yaml new file mode 100644 index 0000000..7ddb909 --- /dev/null +++ b/runs/permits-2026-09-25/questions/decide/objection.yaml @@ -0,0 +1,9 @@ +name: What would you like to do? +description: '' +alternatives: +- name: Withdrawn + description: '' + self_transition: + bucket: objections + to: withdrawn + label: Withdrawn diff --git a/runs/permits-2026-09-25/questions/decide/permit-application.yaml b/runs/permits-2026-09-25/questions/decide/permit-application.yaml new file mode 100644 index 0000000..b90eacf --- /dev/null +++ b/runs/permits-2026-09-25/questions/decide/permit-application.yaml @@ -0,0 +1,15 @@ +name: What would you like to do? +description: '' +alternatives: +- name: Complete + description: '' + self_transition: + bucket: applications + to: complete + label: Complete +- name: Withdrawn + description: '' + self_transition: + bucket: applications + to: withdrawn + label: Withdrawn diff --git a/runs/permits-2026-09-25/questions/decide/pre-application-meeting.yaml b/runs/permits-2026-09-25/questions/decide/pre-application-meeting.yaml new file mode 100644 index 0000000..315bde5 --- /dev/null +++ b/runs/permits-2026-09-25/questions/decide/pre-application-meeting.yaml @@ -0,0 +1,9 @@ +name: What would you like to do? +description: '' +alternatives: +- name: Cancelled + description: '' + self_transition: + bucket: meetings + to: cancelled + label: Cancelled diff --git a/runs/permits-2026-09-25/questions/decide/small-works-application.yaml b/runs/permits-2026-09-25/questions/decide/small-works-application.yaml new file mode 100644 index 0000000..b90eacf --- /dev/null +++ b/runs/permits-2026-09-25/questions/decide/small-works-application.yaml @@ -0,0 +1,15 @@ +name: What would you like to do? +description: '' +alternatives: +- name: Complete + description: '' + self_transition: + bucket: applications + to: complete + label: Complete +- name: Withdrawn + description: '' + self_transition: + bucket: applications + to: withdrawn + label: Withdrawn diff --git a/runs/permits-2026-09-25/questions/front_desk/_section.yaml b/runs/permits-2026-09-25/questions/front_desk/_section.yaml new file mode 100644 index 0000000..8b76bf9 --- /dev/null +++ b/runs/permits-2026-09-25/questions/front_desk/_section.yaml @@ -0,0 +1 @@ +qualifies: front_desk diff --git a/runs/permits-2026-09-25/questions/front_desk/index.yaml b/runs/permits-2026-09-25/questions/front_desk/index.yaml new file mode 100644 index 0000000..b36f594 --- /dev/null +++ b/runs/permits-2026-09-25/questions/front_desk/index.yaml @@ -0,0 +1,157 @@ +name: What needs doing? +description: Everything front desk looks after. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: Appeals + description: Sent in by anyone with an interest who will not accept a decision of ours. + action: /front_desk + consequence: + - Confirm + features: + - name: Appeals + description: Each row is one case and the stage it has reached. Another desk moves these. + resource: + source: + kind: kv + bucket: appeals + requires_group: front_desk + transitions: [] +- name: Applications + description: Sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner. + action: /front_desk + consequence: + - Confirm + features: + - name: Applications + description: Each row is one case and the stage it has reached. Another desk moves these. + resource: + source: + kind: kv + bucket: applications + requires_group: front_desk + transitions: [] +- name: Enquiries + description: Sent in by someone waiting on a case and getting nothing back or whoever is on the counter with a queue and a caller on the line. + action: /front_desk + consequence: + - Confirm + features: + - name: Enquiries + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: enquiries + requires_group: front_desk + transitions: + - from: in_hand + to: answered + label: Answered + - from: open + to: in_hand + label: In hand +- name: Firms + description: Sent in by an architect or engineering firm that files for its clients. + action: /front_desk + consequence: + - Confirm + features: + - name: Firms + description: Each row is one case and the stage it has reached. Another desk moves these. + resource: + source: + kind: kv + bucket: firms + requires_group: front_desk + transitions: [] +- name: Hearing answers + description: Sent in by a road, fire, heritage or county officer who has been asked about a case. + action: /front_desk + consequence: + - Confirm + features: + - name: Hearing answers + description: Each row is one case and the stage it has reached. Another desk moves these. + resource: + source: + kind: kv + bucket: hearing_answers + requires_group: front_desk + transitions: [] +- name: Hearings + description: Sent in by a case officer sending a case out to the authority that must see it. + action: /front_desk + consequence: + - Confirm + features: + - name: Hearings + description: Each row is one case and the stage it has reached. Another desk moves these. + resource: + source: + kind: kv + bucket: hearings + requires_group: front_desk + transitions: [] +- name: Meetings + description: Sent in by someone with an idea for a building and no drawings yet. + action: /front_desk + consequence: + - Confirm + features: + - name: Meetings + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: meetings + requires_group: front_desk + transitions: + - from: met + to: cancelled + label: Cancelled + - from: open + to: cancelled + label: Cancelled + - from: scheduled + to: cancelled + label: Cancelled +- name: the question written down and sent to whoever has the case + description: For whoever is on the counter with a queue and a caller on the line. + action: /front_desk/log-counter-enquiry + consequence: + - Open +- name: Invite someone into Front desk + description: They get an account, a place in Front desk, and a one-time link to set their own password or passkey. + action: /front_desk + consequence: + - Invite + invite: + group: front_desk + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invitations sent + description: Each invite with the link it made. Mark it done when the person is in. + action: /front_desk + consequence: + - Confirm + features: + - name: Who has been invited + description: Each row is one invitation, with the one-time link while it is unused. + resource: + source: + kind: kv + bucket: portal_invites + requires_group: front_desk + transitions: + - from: open + to: done + label: Is in diff --git a/runs/permits-2026-09-25/questions/front_desk/log-counter-enquiry-sent.yaml b/runs/permits-2026-09-25/questions/front_desk/log-counter-enquiry-sent.yaml new file mode 100644 index 0000000..26a8dba --- /dev/null +++ b/runs/permits-2026-09-25/questions/front_desk/log-counter-enquiry-sent.yaml @@ -0,0 +1,10 @@ +name: What happens now? +description: It has reached our front desk. +alternatives: +- name: We read it and come back to you + description: Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example. +- name: Back + description: '' + action: /front_desk + consequence: + - Back diff --git a/runs/permits-2026-09-25/questions/front_desk/log-counter-enquiry.yaml b/runs/permits-2026-09-25/questions/front_desk/log-counter-enquiry.yaml new file mode 100644 index 0000000..fdab619 --- /dev/null +++ b/runs/permits-2026-09-25/questions/front_desk/log-counter-enquiry.yaml @@ -0,0 +1,31 @@ +followup: false +name: Log counter enquiry? +description: '' +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: the question written down and sent to whoever has the case + description: For whoever is on the counter with a queue and a caller on the line. + action: /front_desk/log-counter-enquiry-sent + consequence: + - Send + record_as: enquiries + features: + - name: What happens next + description: It is open, then in hand, and ends answered. + icon: lucide:route + - name: Who reads it + description: Front desk. Questions go to Solveig Hauge at byggesak@vestmark.example. + icon: lucide:users + - name: Details + requirements: + - name: email + label: Email + type: email + - name: case_number_or_address + label: Case number or address + type: text + - name: what_you_want_to_know + label: What you want to know + type: textarea diff --git a/runs/permits-2026-09-25/questions/index.yaml b/runs/permits-2026-09-25/questions/index.yaml new file mode 100644 index 0000000..21c9960 --- /dev/null +++ b/runs/permits-2026-09-25/questions/index.yaml @@ -0,0 +1,127 @@ +name: What brings you here? +description: | + The building authority for twenty-one thousand people. Anything built, demolished, divided or changed in use is decided here: the drawings are checked against the zoning map, the neighbours and the other authorities have their say, and then the head of section signs. The same office inspects what is actually built, signs off finished work, and deals with building nobody applied for. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: What we do + description: '' + features: + - name: Permission to build it, and to know where the case stands + description: | + Everything built in Vestmark is decided here. You send the drawings, the neighbours and the road, fire and heritage authorities are heard, and you get a written decision you can hold us to. + - name: What they think on the record, and answered in the decision + description: | + If a notice landed in your postbox, the case behind it is open to read here, and what you write to us has to be answered by name in the decision. +- name: Have a look around + description: '' + features: + - name: See all appeals + description: Everything sent in by anyone with an interest who will not accept a decision of ours, and where each one stands. [See all appeals](/status/appeals) + icon: lucide:list + - name: See all applications + description: Everything sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner, and where each one stands. [See all applications](/status/applications) + icon: lucide:list + - name: See all completions + description: Everything sent in by an owner or firm whose building work is finished, and where each one stands. [See all completions](/status/completions) + icon: lucide:list + - name: See all exemptions + description: Everything sent in by someone whose plans break a rule in the zoning map, and where each one stands. [See all exemptions](/status/exemptions) + icon: lucide:list + - name: See all objections + description: Everything sent in by a neighbour who got a notice about what is planned next door, and where each one stands. [See all objections](/status/objections) + icon: lucide:list +- name: Want to build + description: For an owner or a firm with something to build, divide or change. + action: /want-to-build + consequence: + - Continue + features: + - name: '' + description: To hear what we will allow before paying an architect, permission to build it, and to know where the case stands, to be allowed it anyway, with reasons on the record, the certificate that lets the building be used. +- name: Building near me + description: For someone who lives next to what is being built. + action: /building-near-me + consequence: + - Continue + features: + - name: '' + description: What they think on the record, and answered in the decision, to be told where it actually stands, us to go and look, and to hear that we did. +- name: the decision looked at again, by us and then by the board + description: For anyone with an interest who will not accept a decision of ours. + action: /received/appeal + consequence: + - Send + record_as: appeals + features: + - name: What you need + description: A decision from us less than three weeks old, and its case number. + icon: lucide:key + - name: What happens next + description: It is open, then we are looking at it again, then with the appeals board, and ends we changed our own decision, the board kept our decision, the board overturned us or withdrawn. + icon: lucide:route + - name: Who reads it + description: Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example. + icon: lucide:users + - name: Details + requirements: + - name: email + label: Email + type: email + - name: case_number + label: Case number + type: text + - name: property + label: Property + type: text + - name: what_you_disagree_with + label: What you disagree with + type: textarea + - name: your_interest + label: Your interest + type: select + options: + - I applied + - I am a neighbour + - Other +- name: to be on the list, and then to file without asking again + description: For an architect or engineering firm that files for its clients. + action: /received/firm-approval + consequence: + - Send + record_as: firms + features: + - name: What happens next + description: It is open, then waiting on papers, then papers checked, and ends approved or declined. + icon: lucide:route + - name: Who reads it + description: Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example. + icon: lucide:users + - name: Details + requirements: + - name: firm_name + label: Firm name + type: text + - name: org_number + label: Org number + type: text + - name: email + label: Email + type: email + - name: qualified_for + label: Qualified for + type: select + options: + - Design + - Execution + - Independent control + - Site management + multiple: true + - name: insurance_expires + label: Insurance expires + type: date + - name: insurance_document + label: Insurance document + type: text + optional: true diff --git a/runs/permits-2026-09-25/questions/inspectors/_section.yaml b/runs/permits-2026-09-25/questions/inspectors/_section.yaml new file mode 100644 index 0000000..d41d53f --- /dev/null +++ b/runs/permits-2026-09-25/questions/inspectors/_section.yaml @@ -0,0 +1 @@ +qualifies: inspectors diff --git a/runs/permits-2026-09-25/questions/inspectors/index.yaml b/runs/permits-2026-09-25/questions/inspectors/index.yaml new file mode 100644 index 0000000..f6a397a --- /dev/null +++ b/runs/permits-2026-09-25/questions/inspectors/index.yaml @@ -0,0 +1,118 @@ +name: What needs doing? +description: Everything inspectors looks after. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: Applications + description: Sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner. + action: /inspectors + consequence: + - Confirm + features: + - name: Applications + description: Each row is one case and the stage it has reached. Another desk moves these. + resource: + source: + kind: kv + bucket: applications + requires_group: inspectors + transitions: [] +- name: Completions + description: Sent in by an owner or firm whose building work is finished. + action: /inspectors + consequence: + - Confirm + features: + - name: Completions + description: Each row is one case and the stage it has reached. Another desk moves these. + resource: + source: + kind: kv + bucket: completions + requires_group: inspectors + transitions: [] +- name: Illegal building + description: Sent in by someone who can see building going up that nobody was told about. + action: /inspectors + consequence: + - Confirm + features: + - name: Illegal building + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: illegal_building + requires_group: inspectors + transitions: + - from: explained + to: resolved + label: Resolved + - from: explained + to: dropped + label: Nothing to pursue + - from: open + to: inspected + label: Inspected +- name: Inspections + description: Sent in by an inspector on a scaffold with gloves on and the wind blowing. + action: /inspectors + consequence: + - Confirm + features: + - name: Inspections + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: inspections + requires_group: inspectors + transitions: + - from: deviation + to: as_approved + label: Built as approved + - from: deviation + to: put_right + label: Put right + - from: open + to: deviation + label: Built differently +- name: what they found logged before they climb down + description: For an inspector on a scaffold with gloves on and the wind blowing. + action: /inspectors/inspection-finding + consequence: + - Open +- name: Invite someone into Inspectors + description: They get an account, a place in Inspectors, and a one-time link to set their own password or passkey. + action: /inspectors + consequence: + - Invite + invite: + group: inspectors + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invitations sent + description: Each invite with the link it made. Mark it done when the person is in. + action: /inspectors + consequence: + - Confirm + features: + - name: Who has been invited + description: Each row is one invitation, with the one-time link while it is unused. + resource: + source: + kind: kv + bucket: portal_invites + requires_group: inspectors + transitions: + - from: open + to: done + label: Is in diff --git a/runs/permits-2026-09-25/questions/inspectors/inspection-finding-sent.yaml b/runs/permits-2026-09-25/questions/inspectors/inspection-finding-sent.yaml new file mode 100644 index 0000000..ac8e8b2 --- /dev/null +++ b/runs/permits-2026-09-25/questions/inspectors/inspection-finding-sent.yaml @@ -0,0 +1,10 @@ +name: What happens now? +description: It has reached our inspectors. +alternatives: +- name: We read it and come back to you + description: Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example. +- name: Back + description: '' + action: /inspectors + consequence: + - Back diff --git a/runs/permits-2026-09-25/questions/inspectors/inspection-finding.yaml b/runs/permits-2026-09-25/questions/inspectors/inspection-finding.yaml new file mode 100644 index 0000000..18b5d32 --- /dev/null +++ b/runs/permits-2026-09-25/questions/inspectors/inspection-finding.yaml @@ -0,0 +1,35 @@ +followup: false +name: Inspection finding? +description: '' +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: what they found logged before they climb down + description: For an inspector on a scaffold with gloves on and the wind blowing. + action: /inspectors/inspection-finding-sent + consequence: + - Send + record_as: inspections + features: + - name: What happens next + description: It is open, then built differently, and ends built as approved, put right or handed to a case officer. + icon: lucide:route + - name: Who reads it + description: Inspectors. Questions go to Solveig Hauge at byggesak@vestmark.example. + icon: lucide:users + - name: Details + requirements: + - name: case_number + label: Case number + type: text + - name: site_address + label: Site address + type: text + - name: what_i_found + label: What i found + type: textarea + - name: where + label: Where + type: location + optional: true diff --git a/runs/permits-2026-09-25/questions/received/appeal.yaml b/runs/permits-2026-09-25/questions/received/appeal.yaml new file mode 100644 index 0000000..6148787 --- /dev/null +++ b/runs/permits-2026-09-25/questions/received/appeal.yaml @@ -0,0 +1,15 @@ +name: What happens now? +description: It has reached our case officers. +alternatives: +- name: We read it and come back to you + description: Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example. +- name: See all appeals + description: '' + action: /status/appeals + consequence: + - Open +- name: Back + description: '' + action: / + consequence: + - Back diff --git a/runs/permits-2026-09-25/questions/received/case-status-enquiry.yaml b/runs/permits-2026-09-25/questions/received/case-status-enquiry.yaml new file mode 100644 index 0000000..7150e83 --- /dev/null +++ b/runs/permits-2026-09-25/questions/received/case-status-enquiry.yaml @@ -0,0 +1,10 @@ +name: What happens now? +description: It has reached our front desk. +alternatives: +- name: We read it and come back to you + description: Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example. +- name: Back + description: '' + action: / + consequence: + - Back diff --git a/runs/permits-2026-09-25/questions/received/completion-request.yaml b/runs/permits-2026-09-25/questions/received/completion-request.yaml new file mode 100644 index 0000000..93e37f8 --- /dev/null +++ b/runs/permits-2026-09-25/questions/received/completion-request.yaml @@ -0,0 +1,15 @@ +name: What happens now? +description: It has reached our case officers. +alternatives: +- name: We read it and come back to you + description: Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example. +- name: See all completions + description: '' + action: /status/completions + consequence: + - Open +- name: Back + description: '' + action: / + consequence: + - Back diff --git a/runs/permits-2026-09-25/questions/received/exemption-request.yaml b/runs/permits-2026-09-25/questions/received/exemption-request.yaml new file mode 100644 index 0000000..04c3fe3 --- /dev/null +++ b/runs/permits-2026-09-25/questions/received/exemption-request.yaml @@ -0,0 +1,15 @@ +name: What happens now? +description: It has reached our case officers. +alternatives: +- name: We read it and come back to you + description: Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example. +- name: See all exemptions + description: '' + action: /status/exemptions + consequence: + - Open +- name: Back + description: '' + action: / + consequence: + - Back diff --git a/runs/permits-2026-09-25/questions/received/firm-approval.yaml b/runs/permits-2026-09-25/questions/received/firm-approval.yaml new file mode 100644 index 0000000..71486fa --- /dev/null +++ b/runs/permits-2026-09-25/questions/received/firm-approval.yaml @@ -0,0 +1,10 @@ +name: What happens now? +description: It has reached our case officers. +alternatives: +- name: We read it and come back to you + description: Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example. +- name: Back + description: '' + action: / + consequence: + - Back diff --git a/runs/permits-2026-09-25/questions/received/illegal-building-report.yaml b/runs/permits-2026-09-25/questions/received/illegal-building-report.yaml new file mode 100644 index 0000000..1dad0c2 --- /dev/null +++ b/runs/permits-2026-09-25/questions/received/illegal-building-report.yaml @@ -0,0 +1,10 @@ +name: What happens now? +description: It has reached our inspectors. +alternatives: +- name: We read it and come back to you + description: Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example. +- name: Back + description: '' + action: / + consequence: + - Back diff --git a/runs/permits-2026-09-25/questions/received/objection.yaml b/runs/permits-2026-09-25/questions/received/objection.yaml new file mode 100644 index 0000000..c75f760 --- /dev/null +++ b/runs/permits-2026-09-25/questions/received/objection.yaml @@ -0,0 +1,15 @@ +name: What happens now? +description: It has reached our case officers. +alternatives: +- name: We read it and come back to you + description: Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example. +- name: See all objections + description: '' + action: /status/objections + consequence: + - Open +- name: Back + description: '' + action: / + consequence: + - Back diff --git a/runs/permits-2026-09-25/questions/received/pre-application-meeting.yaml b/runs/permits-2026-09-25/questions/received/pre-application-meeting.yaml new file mode 100644 index 0000000..71486fa --- /dev/null +++ b/runs/permits-2026-09-25/questions/received/pre-application-meeting.yaml @@ -0,0 +1,10 @@ +name: What happens now? +description: It has reached our case officers. +alternatives: +- name: We read it and come back to you + description: Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example. +- name: Back + description: '' + action: / + consequence: + - Back diff --git a/runs/permits-2026-09-25/questions/received/small-works-application.yaml b/runs/permits-2026-09-25/questions/received/small-works-application.yaml new file mode 100644 index 0000000..6e621eb --- /dev/null +++ b/runs/permits-2026-09-25/questions/received/small-works-application.yaml @@ -0,0 +1,15 @@ +name: What happens now? +description: It has reached our case officers. +alternatives: +- name: We read it and come back to you + description: Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example. +- name: See all applications + description: '' + action: /status/applications + consequence: + - Open +- name: Back + description: '' + action: / + consequence: + - Back diff --git a/runs/permits-2026-09-25/questions/section_head/_section.yaml b/runs/permits-2026-09-25/questions/section_head/_section.yaml new file mode 100644 index 0000000..569137f --- /dev/null +++ b/runs/permits-2026-09-25/questions/section_head/_section.yaml @@ -0,0 +1 @@ +qualifies: section_head diff --git a/runs/permits-2026-09-25/questions/section_head/index.yaml b/runs/permits-2026-09-25/questions/section_head/index.yaml new file mode 100644 index 0000000..deed9ce --- /dev/null +++ b/runs/permits-2026-09-25/questions/section_head/index.yaml @@ -0,0 +1,350 @@ +name: What needs doing? +description: Everything head of section looks after. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: Appeals + description: Sent in by anyone with an interest who will not accept a decision of ours. + action: /section_head + consequence: + - Confirm + features: + - name: Appeals + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: appeals + requires_group: section_head + transitions: + - from: reconsidered + to: before_the_board + label: With the appeals board + - from: reconsidered + to: changed_by_us + label: We changed our own decision +- name: Applications + description: Sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner. + action: /section_head + consequence: + - Confirm + features: + - name: Applications + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: applications + requires_group: section_head + transitions: + - from: complete + to: refused + label: Refused + - from: on_hearing + to: refused + label: Refused + - from: recommended + to: approved + label: Approved + - from: recommended + to: approved_with_conditions + label: Approved on conditions + - from: recommended + to: refused + label: Refused +- name: Completions + description: Sent in by an owner or firm whose building work is finished. + action: /section_head + consequence: + - Confirm + features: + - name: Completions + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: completions + requires_group: section_head + transitions: + - from: checked + to: temporary_permission + label: Temporary permission to use + - from: checked + to: certificate_issued + label: Certificate issued + - from: checked + to: refused + label: Refused + - from: open + to: refused + label: Refused + - from: temporary_permission + to: certificate_issued + label: Certificate issued +- name: Exemptions + description: Sent in by someone whose plans break a rule in the zoning map. + action: /section_head + consequence: + - Confirm + features: + - name: Exemptions + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: exemptions + requires_group: section_head + transitions: + - from: county_answered + to: denied + label: Denied + - from: county_asked + to: denied + label: Denied + - from: open + to: denied + label: Denied + - from: recommended + to: granted + label: Granted + - from: recommended + to: denied + label: Denied +- name: Firms + description: Sent in by an architect or engineering firm that files for its clients. + action: /section_head + consequence: + - Confirm + features: + - name: Firms + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: firms + requires_group: section_head + transitions: + - from: checked + to: approved + label: Approved + - from: checked + to: declined + label: Declined + - from: open + to: declined + label: Declined + - from: papers_missing + to: declined + label: Declined +- name: Hearing answers + description: Sent in by a road, fire, heritage or county officer who has been asked about a case. + action: /section_head + consequence: + - Confirm + features: + - name: Hearing answers + description: Each row is one case and the stage it has reached. Another desk moves these. + resource: + source: + kind: kv + bucket: hearing_answers + requires_group: section_head + transitions: [] +- name: Hearings + description: Sent in by a case officer sending a case out to the authority that must see it. + action: /section_head + consequence: + - Confirm + features: + - name: Hearings + description: Each row is one case and the stage it has reached. Another desk moves these. + resource: + source: + kind: kv + bucket: hearings + requires_group: section_head + transitions: [] +- name: Illegal building + description: Sent in by someone who can see building going up that nobody was told about. + action: /section_head + consequence: + - Confirm + features: + - name: Illegal building + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: illegal_building + requires_group: section_head + transitions: + - from: inspected + to: fined + label: Fined + - from: open + to: fined + label: Fined +- name: Inspections + description: Sent in by an inspector on a scaffold with gloves on and the wind blowing. + action: /section_head + consequence: + - Confirm + features: + - name: Inspections + description: Each row is one case. The buttons record what you have just done with it. + resource: + source: + kind: kv + bucket: inspections + requires_group: section_head + transitions: + - from: deviation + to: escalated + label: Handed to a case officer + - from: open + to: escalated + label: Handed to a case officer +- name: Objections + description: Sent in by a neighbour who got a notice about what is planned next door. + action: /section_head + consequence: + - Confirm + features: + - name: Objections + description: Each row is one case and the stage it has reached. Another desk moves these. + resource: + source: + kind: kv + bucket: objections + requires_group: section_head + transitions: [] +- name: Invite someone into Hearing bodies + description: They get an account, a place in Hearing bodies, and a one-time link to set their own password or passkey. + action: /section_head + consequence: + - Invite + invite: + group: agencies + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invite someone into Appeals board + description: They get an account, a place in Appeals board, and a one-time link to set their own password or passkey. + action: /section_head + consequence: + - Invite + invite: + group: appeals_board + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invite someone into Approved firms + description: They get an account, a place in Approved firms, and a one-time link to set their own password or passkey. + action: /section_head + consequence: + - Invite + invite: + group: approved_firms + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invite someone into Case officers + description: They get an account, a place in Case officers, and a one-time link to set their own password or passkey. + action: /section_head + consequence: + - Invite + invite: + group: case_officers + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invite someone into Front desk + description: They get an account, a place in Front desk, and a one-time link to set their own password or passkey. + action: /section_head + consequence: + - Invite + invite: + group: front_desk + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invite someone into Inspectors + description: They get an account, a place in Inspectors, and a one-time link to set their own password or passkey. + action: /section_head + consequence: + - Invite + invite: + group: inspectors + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invite someone into Head of section + description: They get an account, a place in Head of section, and a one-time link to set their own password or passkey. + action: /section_head + consequence: + - Invite + invite: + group: section_head + features: + - name: Who + description: Their name, and the address the account and its one-time link go to. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email +- name: Invitations sent + description: Each invite with the link it made. Mark it done when the person is in. + action: /section_head + consequence: + - Confirm + features: + - name: Who has been invited + description: Each row is one invitation, with the one-time link while it is unused. + resource: + source: + kind: kv + bucket: portal_invites + requires_group: section_head + transitions: + - from: open + to: done + label: Is in diff --git a/runs/permits-2026-09-25/questions/status/appeals/index.yaml b/runs/permits-2026-09-25/questions/status/appeals/index.yaml new file mode 100644 index 0000000..662ae18 --- /dev/null +++ b/runs/permits-2026-09-25/questions/status/appeals/index.yaml @@ -0,0 +1,22 @@ +name: What has been sent in about appeals? +description: Everything sent in by anyone with an interest who will not accept a decision of ours, and where each one stands. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: Appeals + description: '' + features: + - name: Appeals + description: Each row is one case and the stage it has reached. Names and contact details are not shown here. + resource: + source: + kind: kv + bucket: appeals + public: true + jq: '.[] | .responses |= {case_number: .case_number, property: .property, what_you_disagree_with: .what_you_disagree_with, your_interest: .your_interest}' +- name: Back + description: '' + action: / + consequence: + - Back diff --git a/runs/permits-2026-09-25/questions/status/applications/index.yaml b/runs/permits-2026-09-25/questions/status/applications/index.yaml new file mode 100644 index 0000000..3146555 --- /dev/null +++ b/runs/permits-2026-09-25/questions/status/applications/index.yaml @@ -0,0 +1,22 @@ +name: What has been sent in about applications? +description: Everything sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner, and where each one stands. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: Applications + description: '' + features: + - name: Applications + description: Each row is one case and the stage it has reached. Names and contact details are not shown here. + resource: + source: + kind: kv + bucket: applications + public: true + jq: '.[] | .responses |= {drawings_url: .drawings_url, neighbours_notified: .neighbours_notified, property_address: .property_address, property_number: .property_number, site: .site, what_is_planned: .what_is_planned}' +- name: Back + description: '' + action: / + consequence: + - Back diff --git a/runs/permits-2026-09-25/questions/status/completions/index.yaml b/runs/permits-2026-09-25/questions/status/completions/index.yaml new file mode 100644 index 0000000..c635e35 --- /dev/null +++ b/runs/permits-2026-09-25/questions/status/completions/index.yaml @@ -0,0 +1,22 @@ +name: What has been sent in about completions? +description: Everything sent in by an owner or firm whose building work is finished, and where each one stands. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: Completions + description: '' + features: + - name: Completions + description: Each row is one case and the stage it has reached. Names and contact details are not shown here. + resource: + source: + kind: kv + bucket: completions + public: true + jq: '.[] | .responses |= {asking_for: .asking_for, case_number: .case_number, property_address: .property_address, what_is_outstanding: .what_is_outstanding, work_finished: .work_finished}' +- name: Back + description: '' + action: / + consequence: + - Back diff --git a/runs/permits-2026-09-25/questions/status/exemptions/index.yaml b/runs/permits-2026-09-25/questions/status/exemptions/index.yaml new file mode 100644 index 0000000..7bc890c --- /dev/null +++ b/runs/permits-2026-09-25/questions/status/exemptions/index.yaml @@ -0,0 +1,22 @@ +name: What has been sent in about exemptions? +description: Everything sent in by someone whose plans break a rule in the zoning map, and where each one stands. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: Exemptions + description: '' + features: + - name: Exemptions + description: Each row is one case and the stage it has reached. Names and contact details are not shown here. + resource: + source: + kind: kv + bucket: exemptions + public: true + jq: '.[] | .responses |= {case_number: .case_number, site: .site, which_rule: .which_rule, why_it_should_be_allowed: .why_it_should_be_allowed}' +- name: Back + description: '' + action: / + consequence: + - Back diff --git a/runs/permits-2026-09-25/questions/status/objections/index.yaml b/runs/permits-2026-09-25/questions/status/objections/index.yaml new file mode 100644 index 0000000..416efb6 --- /dev/null +++ b/runs/permits-2026-09-25/questions/status/objections/index.yaml @@ -0,0 +1,22 @@ +name: What has been sent in about objections? +description: Everything sent in by a neighbour who got a notice about what is planned next door, and where each one stands. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: Objections + description: '' + features: + - name: Objections + description: Each row is one case and the stage it has reached. Names and contact details are not shown here. + resource: + source: + kind: kv + bucket: objections + public: true + jq: '.[] | .responses |= {case_number: .case_number, your_objection: .your_objection, your_property: .your_property}' +- name: Back + description: '' + action: / + consequence: + - Back diff --git a/runs/permits-2026-09-25/questions/want-to-build/index.yaml b/runs/permits-2026-09-25/questions/want-to-build/index.yaml new file mode 100644 index 0000000..4b3e350 --- /dev/null +++ b/runs/permits-2026-09-25/questions/want-to-build/index.yaml @@ -0,0 +1,156 @@ +name: What do you need? +description: For an owner or a firm with something to build, divide or change. +responsible: + name: Solveig Hauge + contact: byggesak@vestmark.example +alternatives: +- name: to hear what we will allow before paying an architect + description: For someone with an idea for a building and no drawings yet. + action: /received/pre-application-meeting + consequence: + - Send + record_as: meetings + features: + - name: What happens next + description: It is open, then scheduled, then we have met, and ends written advice sent or cancelled. + icon: lucide:route + - name: Who reads it + description: Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example. + icon: lucide:users + - name: Details + requirements: + - name: name + label: Name + type: text + - name: email + label: Email + type: email + - name: property_address + label: Property address + type: text + - name: what_you_want + label: What you want + type: textarea + - name: phone + label: Phone + type: tel + optional: true + - name: site + label: Site + type: location + optional: true +- name: permission to build it, and to know where the case stands + description: For an owner applying for something small enough to file themselves. + action: /received/small-works-application + consequence: + - Send + record_as: applications + features: + - name: What happens next + description: It is open, then papers missing, then papers complete, then out to the neighbours and the agencies, then recommendation written, and ends approved, approved on conditions, refused or withdrawn. + icon: lucide:route + - name: Who reads it + description: Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example. + icon: lucide:users + - name: Details + requirements: + - name: email + label: Email + type: email + - name: property_address + label: Property address + type: text + - name: property_number + label: Property number + type: text + - name: what_is_planned + label: What is planned + type: textarea + - name: neighbours_notified + label: Neighbours notified + type: select + options: + - Yes + - Not yet + - name: site + label: Site + type: location + optional: true + - name: drawings_url + label: Drawings url + type: text + optional: true +- name: to be allowed it anyway, with reasons on the record + description: For someone whose plans break a rule in the zoning map. + action: /received/exemption-request + consequence: + - Send + record_as: exemptions + features: + - name: What you need + description: An application already with us, and the case number from its receipt. + icon: lucide:key + - name: What happens next + description: It is open, then with the county, then the county has answered, then recommended, and ends granted, denied or withdrawn. + icon: lucide:route + - name: Who reads it + description: Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example. + icon: lucide:users + - name: Details + requirements: + - name: email + label: Email + type: email + - name: case_number + label: Case number + type: text + - name: which_rule + label: Which rule + type: text + - name: why_it_should_be_allowed + label: Why it should be allowed + type: textarea + - name: site + label: Site + type: location + optional: true +- name: the certificate that lets the building be used + description: For an owner or firm whose building work is finished. + action: /received/completion-request + consequence: + - Send + record_as: completions + features: + - name: What you need + description: A case number, and the work finished or close enough to move in. + icon: lucide:key + - name: What happens next + description: It is open, then checked against the inspections, then temporary permission to use, and ends certificate issued or refused. + icon: lucide:route + - name: Who reads it + description: Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example. + icon: lucide:users + - name: Details + requirements: + - name: email + label: Email + type: email + - name: case_number + label: Case number + type: text + - name: property_address + label: Property address + type: text + - name: work_finished + label: Work finished + type: date + - name: asking_for + label: Asking for + type: select + options: + - Completion certificate + - Temporary permission to move in + - name: what_is_outstanding + label: What is outstanding + type: textarea + optional: true diff --git a/runs/permits-2026-09-25/site.yaml b/runs/permits-2026-09-25/site.yaml new file mode 100644 index 0000000..9d30842 --- /dev/null +++ b/runs/permits-2026-09-25/site.yaml @@ -0,0 +1,5 @@ +title: Vestmark kommune - Building and Planning +lang: en +mail: + from: Vestmark Building and Planning + reply_to: byggesak@vestmark.example diff --git a/runs/permits-2026-09-25/tasks-full.jsonl b/runs/permits-2026-09-25/tasks-full.jsonl new file mode 100644 index 0000000..883a425 --- /dev/null +++ b/runs/permits-2026-09-25/tasks-full.jsonl @@ -0,0 +1,25 @@ +{"id":"garage-owner@/","persona":"garage-owner","need":"pre-application-meeting","page":"/","state":{"body":"We want to put a double garage where the old shed is. Before I pay an architect I'd like to know whether you'll even allow it, because the neighbour says it's too close to the road.","page":"What we do Permission to build it, and to know where the case stands: Everything built in Vestmark is decided here. You send the drawings, the neighbours and the road, fire and heritage authorities are heard, and you get a written decision you can hold us to. What they think on the record, and answered in the decision: If a notice landed in your postbox, the case behind it is open to read here, and what you write to us has to be answered by name in the decision.\nHave a look around See all appeals: Everything sent in by anyone with an interest who will not accept a decision of ours, and where each one stands. [See all appeals](/status/appeals) See all applications: Everything sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner, and where each one stands. [See all applications](/status/applications) See all completions: Everything sent in by an owner or firm whose building work is finished, and where each one stands. [See all completions](/status/completions) See all exemptions: Everything sent in by someone whose plans break a rule in the zoning map, and where each one stands. [See all exemptions](/status/exemptions) See all objections: Everything sent in by a neighbour who got a notice about what is planned next door, and where each one stands. [See all objections](/status/objections)"},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Building near me":"For someone who lives next to what is being built.","Want to build":"For an owner or a firm with something to build, divide or change.","the decision looked at again, by us and then by the board":"For anyone with an interest who will not accept a decision of ours.","to be on the list, and then to file without asking again":"For an architect or engineering firm that files for its clients."}}},"expect":["Want to build"]} +{"id":"garage-owner@/want-to-build","persona":"garage-owner","need":"pre-application-meeting","page":"/want-to-build","state":{"body":"We want to put a double garage where the old shed is. Before I pay an architect I'd like to know whether you'll even allow it, because the neighbour says it's too close to the road."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What do you need?\". Which alternative do they choose?","criteria":{"permission to build it, and to know where the case stands":"For an owner applying for something small enough to file themselves.","the certificate that lets the building be used":"For an owner or firm whose building work is finished.","to be allowed it anyway, with reasons on the record":"For someone whose plans break a rule in the zoning map.","to hear what we will allow before paying an architect":"For someone with an idea for a building and no drawings yet."}}},"expect":["to hear what we will allow before paying an architect"]} +{"id":"shop-to-flats@/","persona":"shop-to-flats","need":"pre-application-meeting","page":"/","state":{"body":"I own the old grocery on Torget and want to make four flats out of it. There are a lot of questions - parking, fire, the facade is listed. Can we sit down with someone?","page":"What we do Permission to build it, and to know where the case stands: Everything built in Vestmark is decided here. You send the drawings, the neighbours and the road, fire and heritage authorities are heard, and you get a written decision you can hold us to. What they think on the record, and answered in the decision: If a notice landed in your postbox, the case behind it is open to read here, and what you write to us has to be answered by name in the decision.\nHave a look around See all appeals: Everything sent in by anyone with an interest who will not accept a decision of ours, and where each one stands. [See all appeals](/status/appeals) See all applications: Everything sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner, and where each one stands. [See all applications](/status/applications) See all completions: Everything sent in by an owner or firm whose building work is finished, and where each one stands. [See all completions](/status/completions) See all exemptions: Everything sent in by someone whose plans break a rule in the zoning map, and where each one stands. [See all exemptions](/status/exemptions) See all objections: Everything sent in by a neighbour who got a notice about what is planned next door, and where each one stands. [See all objections](/status/objections)"},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Building near me":"For someone who lives next to what is being built.","Want to build":"For an owner or a firm with something to build, divide or change.","the decision looked at again, by us and then by the board":"For anyone with an interest who will not accept a decision of ours.","to be on the list, and then to file without asking again":"For an architect or engineering firm that files for its clients."}}},"expect":["Want to build"]} +{"id":"shop-to-flats@/want-to-build","persona":"shop-to-flats","need":"pre-application-meeting","page":"/want-to-build","state":{"body":"I own the old grocery on Torget and want to make four flats out of it. There are a lot of questions - parking, fire, the facade is listed. Can we sit down with someone?"},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What do you need?\". Which alternative do they choose?","criteria":{"permission to build it, and to know where the case stands":"For an owner applying for something small enough to file themselves.","the certificate that lets the building be used":"For an owner or firm whose building work is finished.","to be allowed it anyway, with reasons on the record":"For someone whose plans break a rule in the zoning map.","to hear what we will allow before paying an architect":"For someone with an idea for a building and no drawings yet."}}},"expect":["to hear what we will allow before paying an architect"]} +{"id":"too-close-to-boundary@/","persona":"too-close-to-boundary","need":"exemption-request","page":"/","state":{"body":"The garage ends up one and a half metres from the boundary and the plan says four. We are asking you to allow it anyway - the ground falls away steeply everywhere else on the plot.","page":"What we do Permission to build it, and to know where the case stands: Everything built in Vestmark is decided here. You send the drawings, the neighbours and the road, fire and heritage authorities are heard, and you get a written decision you can hold us to. What they think on the record, and answered in the decision: If a notice landed in your postbox, the case behind it is open to read here, and what you write to us has to be answered by name in the decision.\nHave a look around See all appeals: Everything sent in by anyone with an interest who will not accept a decision of ours, and where each one stands. [See all appeals](/status/appeals) See all applications: Everything sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner, and where each one stands. [See all applications](/status/applications) See all completions: Everything sent in by an owner or firm whose building work is finished, and where each one stands. [See all completions](/status/completions) See all exemptions: Everything sent in by someone whose plans break a rule in the zoning map, and where each one stands. [See all exemptions](/status/exemptions) See all objections: Everything sent in by a neighbour who got a notice about what is planned next door, and where each one stands. [See all objections](/status/objections)"},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Building near me":"For someone who lives next to what is being built.","Want to build":"For an owner or a firm with something to build, divide or change.","the decision looked at again, by us and then by the board":"For anyone with an interest who will not accept a decision of ours.","to be on the list, and then to file without asking again":"For an architect or engineering firm that files for its clients."}}},"expect":["Want to build"]} +{"id":"too-close-to-boundary@/want-to-build","persona":"too-close-to-boundary","need":"exemption-request","page":"/want-to-build","state":{"body":"The garage ends up one and a half metres from the boundary and the plan says four. We are asking you to allow it anyway - the ground falls away steeply everywhere else on the plot."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What do you need?\". Which alternative do they choose?","criteria":{"permission to build it, and to know where the case stands":"For an owner applying for something small enough to file themselves.","the certificate that lets the building be used":"For an owner or firm whose building work is finished.","to be allowed it anyway, with reasons on the record":"For someone whose plans break a rule in the zoning map.","to hear what we will allow before paying an architect":"For someone with an idea for a building and no drawings yet."}}},"expect":["to be allowed it anyway, with reasons on the record"]} +{"id":"neighbour-view@/","persona":"neighbour-view","need":"objection","page":"/","state":{"body":"I got a notice about the extension at number 14. It takes the afternoon sun off my entire terrace and I want that on the record before you decide anything.","page":"What we do Permission to build it, and to know where the case stands: Everything built in Vestmark is decided here. You send the drawings, the neighbours and the road, fire and heritage authorities are heard, and you get a written decision you can hold us to. What they think on the record, and answered in the decision: If a notice landed in your postbox, the case behind it is open to read here, and what you write to us has to be answered by name in the decision.\nHave a look around See all appeals: Everything sent in by anyone with an interest who will not accept a decision of ours, and where each one stands. [See all appeals](/status/appeals) See all applications: Everything sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner, and where each one stands. [See all applications](/status/applications) See all completions: Everything sent in by an owner or firm whose building work is finished, and where each one stands. [See all completions](/status/completions) See all exemptions: Everything sent in by someone whose plans break a rule in the zoning map, and where each one stands. [See all exemptions](/status/exemptions) See all objections: Everything sent in by a neighbour who got a notice about what is planned next door, and where each one stands. [See all objections](/status/objections)"},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Building near me":"For someone who lives next to what is being built.","Want to build":"For an owner or a firm with something to build, divide or change.","the decision looked at again, by us and then by the board":"For anyone with an interest who will not accept a decision of ours.","to be on the list, and then to file without asking again":"For an architect or engineering firm that files for its clients."}}},"expect":["Building near me"]} +{"id":"neighbour-view@/building-near-me","persona":"neighbour-view","need":"objection","page":"/building-near-me","state":{"body":"I got a notice about the extension at number 14. It takes the afternoon sun off my entire terrace and I want that on the record before you decide anything."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What do you need?\". Which alternative do they choose?","criteria":{"to be told where it actually stands":"For someone waiting on a case and getting nothing back.","us to go and look, and to hear that we did":"For someone who can see building going up that nobody was told about.","what they think on the record, and answered in the decision":"For a neighbour who got a notice about what is planned next door."}}},"expect":["what they think on the record, and answered in the decision"]} +{"id":"neighbour-parking@/","persona":"neighbour-parking","need":"objection","page":"/","state":{"body":"The flats they want to build in the old grocery have four parking places for four flats and everyone here already parks on the street. I object.","page":"What we do Permission to build it, and to know where the case stands: Everything built in Vestmark is decided here. You send the drawings, the neighbours and the road, fire and heritage authorities are heard, and you get a written decision you can hold us to. What they think on the record, and answered in the decision: If a notice landed in your postbox, the case behind it is open to read here, and what you write to us has to be answered by name in the decision.\nHave a look around See all appeals: Everything sent in by anyone with an interest who will not accept a decision of ours, and where each one stands. [See all appeals](/status/appeals) See all applications: Everything sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner, and where each one stands. [See all applications](/status/applications) See all completions: Everything sent in by an owner or firm whose building work is finished, and where each one stands. [See all completions](/status/completions) See all exemptions: Everything sent in by someone whose plans break a rule in the zoning map, and where each one stands. [See all exemptions](/status/exemptions) See all objections: Everything sent in by a neighbour who got a notice about what is planned next door, and where each one stands. [See all objections](/status/objections)"},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Building near me":"For someone who lives next to what is being built.","Want to build":"For an owner or a firm with something to build, divide or change.","the decision looked at again, by us and then by the board":"For anyone with an interest who will not accept a decision of ours.","to be on the list, and then to file without asking again":"For an architect or engineering firm that files for its clients."}}},"expect":["Building near me"]} +{"id":"neighbour-parking@/building-near-me","persona":"neighbour-parking","need":"objection","page":"/building-near-me","state":{"body":"The flats they want to build in the old grocery have four parking places for four flats and everyone here already parks on the street. I object."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What do you need?\". Which alternative do they choose?","criteria":{"to be told where it actually stands":"For someone waiting on a case and getting nothing back.","us to go and look, and to hear that we did":"For someone who can see building going up that nobody was told about.","what they think on the record, and answered in the decision":"For a neighbour who got a notice about what is planned next door."}}},"expect":["what they think on the record, and answered in the decision"]} +{"id":"refused-applicant@/","persona":"refused-applicant","need":"appeal","page":"/","state":{"body":"You refused our exemption on the ninth. We don't accept the reasoning - you've allowed the same thing twice in the same street. We're appealing.","page":"What we do Permission to build it, and to know where the case stands: Everything built in Vestmark is decided here. You send the drawings, the neighbours and the road, fire and heritage authorities are heard, and you get a written decision you can hold us to. What they think on the record, and answered in the decision: If a notice landed in your postbox, the case behind it is open to read here, and what you write to us has to be answered by name in the decision.\nHave a look around See all appeals: Everything sent in by anyone with an interest who will not accept a decision of ours, and where each one stands. [See all appeals](/status/appeals) See all applications: Everything sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner, and where each one stands. [See all applications](/status/applications) See all completions: Everything sent in by an owner or firm whose building work is finished, and where each one stands. [See all completions](/status/completions) See all exemptions: Everything sent in by someone whose plans break a rule in the zoning map, and where each one stands. [See all exemptions](/status/exemptions) See all objections: Everything sent in by a neighbour who got a notice about what is planned next door, and where each one stands. [See all objections](/status/objections)"},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Building near me":"For someone who lives next to what is being built.","Want to build":"For an owner or a firm with something to build, divide or change.","the decision looked at again, by us and then by the board":"For anyone with an interest who will not accept a decision of ours.","to be on the list, and then to file without asking again":"For an architect or engineering firm that files for its clients."}}},"expect":["the decision looked at again, by us and then by the board"]} +{"id":"neighbour-appeals@/","persona":"neighbour-appeals","need":"appeal","page":"/","state":{"body":"You approved the extension next door even though I objected. I'm appealing the decision. What do I need to send?","page":"What we do Permission to build it, and to know where the case stands: Everything built in Vestmark is decided here. You send the drawings, the neighbours and the road, fire and heritage authorities are heard, and you get a written decision you can hold us to. What they think on the record, and answered in the decision: If a notice landed in your postbox, the case behind it is open to read here, and what you write to us has to be answered by name in the decision.\nHave a look around See all appeals: Everything sent in by anyone with an interest who will not accept a decision of ours, and where each one stands. [See all appeals](/status/appeals) See all applications: Everything sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner, and where each one stands. [See all applications](/status/applications) See all completions: Everything sent in by an owner or firm whose building work is finished, and where each one stands. [See all completions](/status/completions) See all exemptions: Everything sent in by someone whose plans break a rule in the zoning map, and where each one stands. [See all exemptions](/status/exemptions) See all objections: Everything sent in by a neighbour who got a notice about what is planned next door, and where each one stands. [See all objections](/status/objections)"},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Building near me":"For someone who lives next to what is being built.","Want to build":"For an owner or a firm with something to build, divide or change.","the decision looked at again, by us and then by the board":"For anyone with an interest who will not accept a decision of ours.","to be on the list, and then to file without asking again":"For an architect or engineering firm that files for its clients."}}},"expect":["the decision looked at again, by us and then by the board"]} +{"id":"board-member@/","persona":"board-member","need":"appeal","page":"/","state":{"body":"I sit on the appeals board. I need the case, our own decision, and what the neighbours wrote, before Tuesday.","page":"What we do Permission to build it, and to know where the case stands: Everything built in Vestmark is decided here. You send the drawings, the neighbours and the road, fire and heritage authorities are heard, and you get a written decision you can hold us to. What they think on the record, and answered in the decision: If a notice landed in your postbox, the case behind it is open to read here, and what you write to us has to be answered by name in the decision.\nHave a look around See all appeals: Everything sent in by anyone with an interest who will not accept a decision of ours, and where each one stands. [See all appeals](/status/appeals) See all applications: Everything sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner, and where each one stands. [See all applications](/status/applications) See all completions: Everything sent in by an owner or firm whose building work is finished, and where each one stands. [See all completions](/status/completions) See all exemptions: Everything sent in by someone whose plans break a rule in the zoning map, and where each one stands. [See all exemptions](/status/exemptions) See all objections: Everything sent in by a neighbour who got a notice about what is planned next door, and where each one stands. [See all objections](/status/objections)"},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Building near me":"For someone who lives next to what is being built.","Want to build":"For an owner or a firm with something to build, divide or change.","the decision looked at again, by us and then by the board":"For anyone with an interest who will not accept a decision of ours.","to be on the list, and then to file without asking again":"For an architect or engineering firm that files for its clients."}}},"expect":["the decision looked at again, by us and then by the board"]} +{"id":"firm-wants-certificate@/","persona":"firm-wants-certificate","need":"completion-request","page":"/","state":{"body":"The work at Bjorkeveien 14 is finished and inspected. We're asking for the completion certificate so the owners can get their mortgage released.","page":"What we do Permission to build it, and to know where the case stands: Everything built in Vestmark is decided here. You send the drawings, the neighbours and the road, fire and heritage authorities are heard, and you get a written decision you can hold us to. What they think on the record, and answered in the decision: If a notice landed in your postbox, the case behind it is open to read here, and what you write to us has to be answered by name in the decision.\nHave a look around See all appeals: Everything sent in by anyone with an interest who will not accept a decision of ours, and where each one stands. [See all appeals](/status/appeals) See all applications: Everything sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner, and where each one stands. [See all applications](/status/applications) See all completions: Everything sent in by an owner or firm whose building work is finished, and where each one stands. [See all completions](/status/completions) See all exemptions: Everything sent in by someone whose plans break a rule in the zoning map, and where each one stands. [See all exemptions](/status/exemptions) See all objections: Everything sent in by a neighbour who got a notice about what is planned next door, and where each one stands. [See all objections](/status/objections)"},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Building near me":"For someone who lives next to what is being built.","Want to build":"For an owner or a firm with something to build, divide or change.","the decision looked at again, by us and then by the board":"For anyone with an interest who will not accept a decision of ours.","to be on the list, and then to file without asking again":"For an architect or engineering firm that files for its clients."}}},"expect":["Want to build"]} +{"id":"firm-wants-certificate@/want-to-build","persona":"firm-wants-certificate","need":"completion-request","page":"/want-to-build","state":{"body":"The work at Bjorkeveien 14 is finished and inspected. We're asking for the completion certificate so the owners can get their mortgage released."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What do you need?\". Which alternative do they choose?","criteria":{"permission to build it, and to know where the case stands":"For an owner applying for something small enough to file themselves.","the certificate that lets the building be used":"For an owner or firm whose building work is finished.","to be allowed it anyway, with reasons on the record":"For someone whose plans break a rule in the zoning map.","to hear what we will allow before paying an architect":"For someone with an idea for a building and no drawings yet."}}},"expect":["the certificate that lets the building be used"]} +{"id":"wants-to-move-in@/","persona":"wants-to-move-in","need":"completion-request","page":"/","state":{"body":"The house is done apart from the outside steps, which we can't pour until spring. The family has sold their flat. Can we get a temporary permission to move in?","page":"What we do Permission to build it, and to know where the case stands: Everything built in Vestmark is decided here. You send the drawings, the neighbours and the road, fire and heritage authorities are heard, and you get a written decision you can hold us to. What they think on the record, and answered in the decision: If a notice landed in your postbox, the case behind it is open to read here, and what you write to us has to be answered by name in the decision.\nHave a look around See all appeals: Everything sent in by anyone with an interest who will not accept a decision of ours, and where each one stands. [See all appeals](/status/appeals) See all applications: Everything sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner, and where each one stands. [See all applications](/status/applications) See all completions: Everything sent in by an owner or firm whose building work is finished, and where each one stands. [See all completions](/status/completions) See all exemptions: Everything sent in by someone whose plans break a rule in the zoning map, and where each one stands. [See all exemptions](/status/exemptions) See all objections: Everything sent in by a neighbour who got a notice about what is planned next door, and where each one stands. [See all objections](/status/objections)"},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Building near me":"For someone who lives next to what is being built.","Want to build":"For an owner or a firm with something to build, divide or change.","the decision looked at again, by us and then by the board":"For anyone with an interest who will not accept a decision of ours.","to be on the list, and then to file without asking again":"For an architect or engineering firm that files for its clients."}}},"expect":["Want to build"]} +{"id":"wants-to-move-in@/want-to-build","persona":"wants-to-move-in","need":"completion-request","page":"/want-to-build","state":{"body":"The house is done apart from the outside steps, which we can't pour until spring. The family has sold their flat. Can we get a temporary permission to move in?"},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What do you need?\". Which alternative do they choose?","criteria":{"permission to build it, and to know where the case stands":"For an owner applying for something small enough to file themselves.","the certificate that lets the building be used":"For an owner or firm whose building work is finished.","to be allowed it anyway, with reasons on the record":"For someone whose plans break a rule in the zoning map.","to hear what we will allow before paying an architect":"For someone with an idea for a building and no drawings yet."}}},"expect":["the certificate that lets the building be used"]} +{"id":"something-behind-fence@/","persona":"something-behind-fence","need":"illegal-building-report","page":"/","state":{"body":"There's a large structure going up behind the fence at Solbakken 7. Nobody has had a notice about it and it's been going on for two weeks.","page":"What we do Permission to build it, and to know where the case stands: Everything built in Vestmark is decided here. You send the drawings, the neighbours and the road, fire and heritage authorities are heard, and you get a written decision you can hold us to. What they think on the record, and answered in the decision: If a notice landed in your postbox, the case behind it is open to read here, and what you write to us has to be answered by name in the decision.\nHave a look around See all appeals: Everything sent in by anyone with an interest who will not accept a decision of ours, and where each one stands. [See all appeals](/status/appeals) See all applications: Everything sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner, and where each one stands. [See all applications](/status/applications) See all completions: Everything sent in by an owner or firm whose building work is finished, and where each one stands. [See all completions](/status/completions) See all exemptions: Everything sent in by someone whose plans break a rule in the zoning map, and where each one stands. [See all exemptions](/status/exemptions) See all objections: Everything sent in by a neighbour who got a notice about what is planned next door, and where each one stands. [See all objections](/status/objections)"},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Building near me":"For someone who lives next to what is being built.","Want to build":"For an owner or a firm with something to build, divide or change.","the decision looked at again, by us and then by the board":"For anyone with an interest who will not accept a decision of ours.","to be on the list, and then to file without asking again":"For an architect or engineering firm that files for its clients."}}},"expect":["Building near me"]} +{"id":"something-behind-fence@/building-near-me","persona":"something-behind-fence","need":"illegal-building-report","page":"/building-near-me","state":{"body":"There's a large structure going up behind the fence at Solbakken 7. Nobody has had a notice about it and it's been going on for two weeks."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What do you need?\". Which alternative do they choose?","criteria":{"to be told where it actually stands":"For someone waiting on a case and getting nothing back.","us to go and look, and to hear that we did":"For someone who can see building going up that nobody was told about.","what they think on the record, and answered in the decision":"For a neighbour who got a notice about what is planned next door."}}},"expect":["us to go and look, and to hear that we did"]} +{"id":"owner-explains@/","persona":"owner-explains","need":"illegal-building-report","page":"/","state":{"body":"I got your letter about the terrace. I genuinely did not know it needed an application, it's been there since we moved in. What happens now?","page":"What we do Permission to build it, and to know where the case stands: Everything built in Vestmark is decided here. You send the drawings, the neighbours and the road, fire and heritage authorities are heard, and you get a written decision you can hold us to. What they think on the record, and answered in the decision: If a notice landed in your postbox, the case behind it is open to read here, and what you write to us has to be answered by name in the decision.\nHave a look around See all appeals: Everything sent in by anyone with an interest who will not accept a decision of ours, and where each one stands. [See all appeals](/status/appeals) See all applications: Everything sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner, and where each one stands. [See all applications](/status/applications) See all completions: Everything sent in by an owner or firm whose building work is finished, and where each one stands. [See all completions](/status/completions) See all exemptions: Everything sent in by someone whose plans break a rule in the zoning map, and where each one stands. [See all exemptions](/status/exemptions) See all objections: Everything sent in by a neighbour who got a notice about what is planned next door, and where each one stands. [See all objections](/status/objections)"},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Building near me":"For someone who lives next to what is being built.","Want to build":"For an owner or a firm with something to build, divide or change.","the decision looked at again, by us and then by the board":"For anyone with an interest who will not accept a decision of ours.","to be on the list, and then to file without asking again":"For an architect or engineering firm that files for its clients."}}},"expect":["Building near me"]} +{"id":"owner-explains@/building-near-me","persona":"owner-explains","need":"illegal-building-report","page":"/building-near-me","state":{"body":"I got your letter about the terrace. I genuinely did not know it needed an application, it's been there since we moved in. What happens now?"},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What do you need?\". Which alternative do they choose?","criteria":{"to be told where it actually stands":"For someone waiting on a case and getting nothing back.","us to go and look, and to hear that we did":"For someone who can see building going up that nobody was told about.","what they think on the record, and answered in the decision":"For a neighbour who got a notice about what is planned next door."}}},"expect":["us to go and look, and to hear that we did"]} +{"id":"new-firm@/","persona":"new-firm","need":"firm-approval","page":"/","state":{"body":"We are a three-person architecture firm that has just started. We want to be approved so we can file applications for our clients in your municipality.","page":"What we do Permission to build it, and to know where the case stands: Everything built in Vestmark is decided here. You send the drawings, the neighbours and the road, fire and heritage authorities are heard, and you get a written decision you can hold us to. What they think on the record, and answered in the decision: If a notice landed in your postbox, the case behind it is open to read here, and what you write to us has to be answered by name in the decision.\nHave a look around See all appeals: Everything sent in by anyone with an interest who will not accept a decision of ours, and where each one stands. [See all appeals](/status/appeals) See all applications: Everything sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner, and where each one stands. [See all applications](/status/applications) See all completions: Everything sent in by an owner or firm whose building work is finished, and where each one stands. [See all completions](/status/completions) See all exemptions: Everything sent in by someone whose plans break a rule in the zoning map, and where each one stands. [See all exemptions](/status/exemptions) See all objections: Everything sent in by a neighbour who got a notice about what is planned next door, and where each one stands. [See all objections](/status/objections)"},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Building near me":"For someone who lives next to what is being built.","Want to build":"For an owner or a firm with something to build, divide or change.","the decision looked at again, by us and then by the board":"For anyone with an interest who will not accept a decision of ours.","to be on the list, and then to file without asking again":"For an architect or engineering firm that files for its clients."}}},"expect":["to be on the list, and then to file without asking again"]} +{"id":"firm-insurance-lapsed@/","persona":"firm-insurance-lapsed","need":"firm-approval","page":"/","state":{"body":"You wrote that our liability insurance certificate has expired. We have renewed it, here it is.","page":"What we do Permission to build it, and to know where the case stands: Everything built in Vestmark is decided here. You send the drawings, the neighbours and the road, fire and heritage authorities are heard, and you get a written decision you can hold us to. What they think on the record, and answered in the decision: If a notice landed in your postbox, the case behind it is open to read here, and what you write to us has to be answered by name in the decision.\nHave a look around See all appeals: Everything sent in by anyone with an interest who will not accept a decision of ours, and where each one stands. [See all appeals](/status/appeals) See all applications: Everything sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner, and where each one stands. [See all applications](/status/applications) See all completions: Everything sent in by an owner or firm whose building work is finished, and where each one stands. [See all completions](/status/completions) See all exemptions: Everything sent in by someone whose plans break a rule in the zoning map, and where each one stands. [See all exemptions](/status/exemptions) See all objections: Everything sent in by a neighbour who got a notice about what is planned next door, and where each one stands. [See all objections](/status/objections)"},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Building near me":"For someone who lives next to what is being built.","Want to build":"For an owner or a firm with something to build, divide or change.","the decision looked at again, by us and then by the board":"For anyone with an interest who will not accept a decision of ours.","to be on the list, and then to file without asking again":"For an architect or engineering firm that files for its clients."}}},"expect":["to be on the list, and then to file without asking again"]} +{"id":"where-is-my-case@/","persona":"where-is-my-case","need":"case-status-enquiry","page":"/","state":{"body":"I sent in my application five weeks ago and I've heard nothing. Is anyone looking at it? Is it in the six weeks with the neighbours or is it waiting on me?","page":"What we do Permission to build it, and to know where the case stands: Everything built in Vestmark is decided here. You send the drawings, the neighbours and the road, fire and heritage authorities are heard, and you get a written decision you can hold us to. What they think on the record, and answered in the decision: If a notice landed in your postbox, the case behind it is open to read here, and what you write to us has to be answered by name in the decision.\nHave a look around See all appeals: Everything sent in by anyone with an interest who will not accept a decision of ours, and where each one stands. [See all appeals](/status/appeals) See all applications: Everything sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner, and where each one stands. [See all applications](/status/applications) See all completions: Everything sent in by an owner or firm whose building work is finished, and where each one stands. [See all completions](/status/completions) See all exemptions: Everything sent in by someone whose plans break a rule in the zoning map, and where each one stands. [See all exemptions](/status/exemptions) See all objections: Everything sent in by a neighbour who got a notice about what is planned next door, and where each one stands. [See all objections](/status/objections)"},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Building near me":"For someone who lives next to what is being built.","Want to build":"For an owner or a firm with something to build, divide or change.","the decision looked at again, by us and then by the board":"For anyone with an interest who will not accept a decision of ours.","to be on the list, and then to file without asking again":"For an architect or engineering firm that files for its clients."}}},"expect":["Building near me"]} +{"id":"where-is-my-case@/building-near-me","persona":"where-is-my-case","need":"case-status-enquiry","page":"/building-near-me","state":{"body":"I sent in my application five weeks ago and I've heard nothing. Is anyone looking at it? Is it in the six weeks with the neighbours or is it waiting on me?"},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What do you need?\". Which alternative do they choose?","criteria":{"to be told where it actually stands":"For someone waiting on a case and getting nothing back.","us to go and look, and to hear that we did":"For someone who can see building going up that nobody was told about.","what they think on the record, and answered in the decision":"For a neighbour who got a notice about what is planned next door."}}},"expect":["to be told where it actually stands"]} diff --git a/runs/permits-2026-09-25/words.json b/runs/permits-2026-09-25/words.json new file mode 100644 index 0000000..14a8edb --- /dev/null +++ b/runs/permits-2026-09-25/words.json @@ -0,0 +1,1681 @@ +{ + "aggregates.yaml": { + "appeals": { + "before_the_board": { + "subject": "Vestmark kommune - Building and Planning: Before the board", + "body": "Hello,\n\nWhat you sent about the decision looked at again, by us and then by the board is now with the appeals board.\n\nWhat you can do next: {site}/decide/appeal?chain={chain}&email={email}\n\nSolveig Hauge at byggesak@vestmark.example" + }, + "changed_by_us": { + "subject": "Vestmark kommune - Building and Planning: Changed by us", + "body": "Hello,\n\nWhat you sent about the decision looked at again, by us and then by the board is now we changed our own decision.\n\nSolveig Hauge at byggesak@vestmark.example" + }, + "open": { + "subject": "Vestmark kommune - Building and Planning: Open", + "body": "Hello,\n\nWe have received what you sent about the decision looked at again, by us and then by the board.\n\nWhat you can do next: {site}/decide/appeal?chain={chain}&email={email}\n\nSolveig Hauge at byggesak@vestmark.example" + }, + "overturned": { + "subject": "Vestmark kommune - Building and Planning: Overturned", + "body": "Hello,\n\nWhat you sent about the decision looked at again, by us and then by the board is now the board overturned us.\n\nSolveig Hauge at byggesak@vestmark.example" + }, + "reconsidered": { + "subject": "Vestmark kommune - Building and Planning: Reconsidered", + "body": "Hello,\n\nWhat you sent about the decision looked at again, by us and then by the board is now we are looking at it again.\n\nWhat you can do next: {site}/decide/appeal?chain={chain}&email={email}\n\nSolveig Hauge at byggesak@vestmark.example" + }, + "upheld": { + "subject": "Vestmark kommune - Building and Planning: Upheld", + "body": "Hello,\n\nWhat you sent about the decision looked at again, by us and then by the board is now the board kept our decision.\n\nSolveig Hauge at byggesak@vestmark.example" + } + }, + "applications": { + "approved": { + "subject": "Vestmark kommune - Building and Planning: Approved", + "body": "Hello,\n\nWhat you sent about permission to build it, and to know where the case stands is now approved.\n\nSolveig Hauge at byggesak@vestmark.example" + }, + "approved_with_conditions": { + "subject": "Vestmark kommune - Building and Planning: Approved with conditions", + "body": "Hello,\n\nWhat you sent about permission to build it, and to know where the case stands is now approved on conditions.\n\nSolveig Hauge at byggesak@vestmark.example" + }, + "incomplete": { + "subject": "Vestmark kommune - Building and Planning: Incomplete", + "body": "Hello,\n\nWhat you sent about permission to build it, and to know where the case stands is now papers missing.\n\nWhat you can do next: {site}/decide/small-works-application?chain={chain}&email={email}\n\nSolveig Hauge at byggesak@vestmark.example" + }, + "on_hearing": { + "subject": "Vestmark kommune - Building and Planning: On hearing", + "body": "Hello,\n\nWhat you sent about permission to build it, and to know where the case stands is now out to the neighbours and the agencies.\n\nWhat you can do next: {site}/decide/small-works-application?chain={chain}&email={email}\n\nSolveig Hauge at byggesak@vestmark.example" + }, + "open": { + "subject": "Vestmark kommune - Building and Planning: Open", + "body": "Hello,\n\nWe have received what you sent about permission to build it, and to know where the case stands.\n\nWhat you can do next: {site}/decide/small-works-application?chain={chain}&email={email}\n\nSolveig Hauge at byggesak@vestmark.example" + }, + "refused": { + "subject": "Vestmark kommune - Building and Planning: Refused", + "body": "Hello,\n\nWhat you sent about permission to build it, and to know where the case stands is now refused.\n\nSolveig Hauge at byggesak@vestmark.example" + } + }, + "completions": { + "certificate_issued": { + "subject": "Vestmark kommune - Building and Planning: Certificate issued", + "body": "Hello,\n\nWhat you sent about the certificate that lets the building be used is now certificate issued.\n\nSolveig Hauge at byggesak@vestmark.example" + }, + "open": { + "subject": "Vestmark kommune - Building and Planning: Open", + "body": "Hello,\n\nWe have received what you sent about the certificate that lets the building be used.\n\nSolveig Hauge at byggesak@vestmark.example" + }, + "refused": { + "subject": "Vestmark kommune - Building and Planning: Refused", + "body": "Hello,\n\nWhat you sent about the certificate that lets the building be used is now refused.\n\nSolveig Hauge at byggesak@vestmark.example" + }, + "temporary_permission": { + "subject": "Vestmark kommune - Building and Planning: Temporary permission", + "body": "Hello,\n\nWhat you sent about the certificate that lets the building be used is now temporary permission to use.\n\nSolveig Hauge at byggesak@vestmark.example" + } + }, + "enquiries": { + "answered": { + "subject": "Vestmark kommune - Building and Planning: Answered", + "body": "Hello,\n\nWhat you sent about to be told where it actually stands is now answered.\n\nSolveig Hauge at byggesak@vestmark.example" + }, + "open": { + "subject": "Vestmark kommune - Building and Planning: Open", + "body": "Hello,\n\nWe have received what you sent about to be told where it actually stands.\n\nSolveig Hauge at byggesak@vestmark.example" + } + }, + "exemptions": { + "county_asked": { + "subject": "Vestmark kommune - Building and Planning: County asked", + "body": "Hello,\n\nWhat you sent about to be allowed it anyway, with reasons on the record is now with the county.\n\nWhat you can do next: {site}/decide/exemption-request?chain={chain}&email={email}\n\nSolveig Hauge at byggesak@vestmark.example" + }, + "denied": { + "subject": "Vestmark kommune - Building and Planning: Denied", + "body": "Hello,\n\nWhat you sent about to be allowed it anyway, with reasons on the record is now denied.\n\nSolveig Hauge at byggesak@vestmark.example" + }, + "granted": { + "subject": "Vestmark kommune - Building and Planning: Granted", + "body": "Hello,\n\nWhat you sent about to be allowed it anyway, with reasons on the record is now granted.\n\nSolveig Hauge at byggesak@vestmark.example" + }, + "open": { + "subject": "Vestmark kommune - Building and Planning: Open", + "body": "Hello,\n\nWe have received what you sent about to be allowed it anyway, with reasons on the record.\n\nWhat you can do next: {site}/decide/exemption-request?chain={chain}&email={email}\n\nSolveig Hauge at byggesak@vestmark.example" + } + }, + "firms": { + "approved": { + "subject": "Vestmark kommune - Building and Planning: Approved", + "body": "Hello,\n\nWhat you sent about to be on the list, and then to file without asking again is now approved.\n\nSolveig Hauge at byggesak@vestmark.example" + }, + "declined": { + "subject": "Vestmark kommune - Building and Planning: Declined", + "body": "Hello,\n\nWhat you sent about to be on the list, and then to file without asking again is now declined.\n\nSolveig Hauge at byggesak@vestmark.example" + }, + "open": { + "subject": "Vestmark kommune - Building and Planning: Open", + "body": "Hello,\n\nWe have received what you sent about to be on the list, and then to file without asking again.\n\nWhat you can do next: {site}/decide/firm-approval?chain={chain}&email={email}\n\nSolveig Hauge at byggesak@vestmark.example" + }, + "papers_missing": { + "subject": "Vestmark kommune - Building and Planning: Papers missing", + "body": "Hello,\n\nWhat you sent about to be on the list, and then to file without asking again is now waiting on papers.\n\nWhat you can do next: {site}/decide/firm-approval?chain={chain}&email={email}\n\nSolveig Hauge at byggesak@vestmark.example" + } + }, + "illegal_building": { + "dropped": { + "subject": "Vestmark kommune - Building and Planning: Dropped", + "body": "Hello,\n\nWhat you sent about us to go and look, and to hear that we did is now nothing to pursue.\n\nSolveig Hauge at byggesak@vestmark.example" + }, + "inspected": { + "subject": "Vestmark kommune - Building and Planning: Inspected", + "body": "Hello,\n\nWhat you sent about us to go and look, and to hear that we did is now inspected.\n\nSolveig Hauge at byggesak@vestmark.example" + }, + "open": { + "subject": "Vestmark kommune - Building and Planning: Open", + "body": "Hello,\n\nWe have received what you sent about us to go and look, and to hear that we did.\n\nSolveig Hauge at byggesak@vestmark.example" + }, + "resolved": { + "subject": "Vestmark kommune - Building and Planning: Resolved", + "body": "Hello,\n\nWhat you sent about us to go and look, and to hear that we did is now resolved.\n\nSolveig Hauge at byggesak@vestmark.example" + } + }, + "meetings": { + "advised": { + "subject": "Vestmark kommune - Building and Planning: Advised", + "body": "Hello {name},\n\nWhat you sent about to hear what we will allow before paying an architect is now written advice sent.\n\nSolveig Hauge at byggesak@vestmark.example" + }, + "open": { + "subject": "Vestmark kommune - Building and Planning: Open", + "body": "Hello {name},\n\nWe have received what you sent about to hear what we will allow before paying an architect.\n\nWhat you can do next: {site}/decide/pre-application-meeting?chain={chain}&email={email}\n\nSolveig Hauge at byggesak@vestmark.example" + }, + "scheduled": { + "subject": "Vestmark kommune - Building and Planning: Scheduled", + "body": "Hello {name},\n\nWhat you sent about to hear what we will allow before paying an architect is now scheduled.\n\nWhat you can do next: {site}/decide/pre-application-meeting?chain={chain}&email={email}\n\nSolveig Hauge at byggesak@vestmark.example" + } + }, + "objections": { + "addressed": { + "subject": "Vestmark kommune - Building and Planning: Addressed", + "body": "Hello,\n\nWhat you sent about what they think on the record, and answered in the decision is now answered in the decision.\n\nSolveig Hauge at byggesak@vestmark.example" + }, + "answered_by_applicant": { + "subject": "Vestmark kommune - Building and Planning: Answered by applicant", + "body": "Hello,\n\nWhat you sent about what they think on the record, and answered in the decision is now the applicant has answered.\n\nWhat you can do next: {site}/decide/objection?chain={chain}&email={email}\n\nSolveig Hauge at byggesak@vestmark.example" + }, + "open": { + "subject": "Vestmark kommune - Building and Planning: Open", + "body": "Hello,\n\nWe have received what you sent about what they think on the record, and answered in the decision.\n\nWhat you can do next: {site}/decide/objection?chain={chain}&email={email}\n\nSolveig Hauge at byggesak@vestmark.example" + } + } + }, + "questions/agencies/hearing-answer-sent.yaml": { + "question": "What happens now?", + "description": "It has reached our case officers.", + "next_heading": "We read it and come back to you", + "next_description": "Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example.", + "back": "Back" + }, + "questions/agencies/hearing-answer.yaml": { + "heading": "their answer on the file, in their own words", + "description": "For a road, fire, heritage or county officer who has been asked about a case.", + "button": "Send", + "encouragement": "", + "icon": "", + "requires_title": "What you need", + "requires_description": "The hearing letter we sent you, which has the case number on it.", + "requires_icon": "key", + "road_title": "What happens next", + "road_description": "It is open, then read by the case officer, and ends followed in the decision or set aside with reasons.", + "road_icon": "route", + "who_title": "Who reads it", + "who_description": "Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example.", + "who_icon": "users", + "form_title": "Details", + "form_description": "", + "labels": { + "case_number": "Case number", + "which_authority": "Which authority", + "our_answer": "Our answer", + "what_we_say": "What we say" + }, + "hints": { + "case_number": "", + "which_authority": "", + "our_answer": "", + "what_we_say": "" + }, + "question": "Hearing answer?", + "page_description": "" + }, + "questions/agencies/index.yaml": { + "question": "What needs doing?", + "description": "Everything hearing bodies looks after.", + "confirm": "Confirm", + "buckets": { + "exemptions": { + "heading": "Exemptions", + "description": "Sent in by someone whose plans break a rule in the zoning map.", + "moves": { + "county_asked->county_answered": "The county has answered" + }, + "list_title": "Exemptions", + "list_note": "Each row is one case. The buttons record what you have just done with it." + }, + "hearings": { + "heading": "Hearings", + "description": "Sent in by a case officer sending a case out to the authority that must see it.", + "moves": { + "open->answered": "Answered" + }, + "list_title": "Hearings", + "list_note": "Each row is one case. The buttons record what you have just done with it." + } + }, + "links": { + "hearing-answer": { + "heading": "their answer on the file, in their own words", + "description": "For a road, fire, heritage or county officer who has been asked about a case.", + "button": "Open" + } + }, + "invites": { + "agencies": { + "heading": "Invite someone into Hearing bodies", + "description": "They get an account, a place in Hearing bodies, and a one-time link to set their own password or passkey.", + "button": "Invite", + "form_title": "Who", + "form_description": "Their name, and the address the account and its one-time link go to.", + "labels": { + "name": "Name", + "email": "Email" + } + } + }, + "invited": { + "heading": "Invitations sent", + "description": "Each invite with the link it made. Mark it done when the person is in.", + "done": "Is in", + "list_title": "Who has been invited", + "list_note": "Each row is one invitation, with the one-time link while it is unused." + } + }, + "questions/appeals_board/index.yaml": { + "question": "What needs doing?", + "description": "Everything appeals board looks after.", + "confirm": "Confirm", + "buckets": { + "appeals": { + "heading": "Appeals", + "description": "Sent in by anyone with an interest who will not accept a decision of ours.", + "moves": { + "before_the_board->overturned": "The board overturned us", + "before_the_board->upheld": "The board kept our decision" + }, + "list_title": "Appeals", + "list_note": "Each row is one case. The buttons record what you have just done with it." + } + }, + "links": {}, + "invites": { + "appeals_board": { + "heading": "Invite someone into Appeals board", + "description": "They get an account, a place in Appeals board, and a one-time link to set their own password or passkey.", + "button": "Invite", + "form_title": "Who", + "form_description": "Their name, and the address the account and its one-time link go to.", + "labels": { + "name": "Name", + "email": "Email" + } + } + }, + "invited": { + "heading": "Invitations sent", + "description": "Each invite with the link it made. Mark it done when the person is in.", + "done": "Is in", + "list_title": "Who has been invited", + "list_note": "Each row is one invitation, with the one-time link while it is unused." + } + }, + "questions/approved_firms/index.yaml": { + "question": "What needs doing?", + "description": "Everything approved firms looks after.", + "confirm": "Confirm", + "buckets": { + "objections": { + "heading": "Objections", + "description": "Sent in by a neighbour who got a notice about what is planned next door.", + "moves": { + "registered->answered_by_applicant": "The applicant has answered" + }, + "list_title": "Objections", + "list_note": "Each row is one case. The buttons record what you have just done with it." + } + }, + "links": { + "permit-application": { + "heading": "a decision inside twelve weeks, and to know when the clock stops", + "description": "For an approved firm filing on behalf of an owner.", + "button": "Open" + } + }, + "invites": { + "approved_firms": { + "heading": "Invite someone into Approved firms", + "description": "They get an account, a place in Approved firms, and a one-time link to set their own password or passkey.", + "button": "Invite", + "form_title": "Who", + "form_description": "Their name, and the address the account and its one-time link go to.", + "labels": { + "name": "Name", + "email": "Email" + } + } + }, + "invited": { + "heading": "Invitations sent", + "description": "Each invite with the link it made. Mark it done when the person is in.", + "done": "Is in", + "list_title": "Who has been invited", + "list_note": "Each row is one invitation, with the one-time link while it is unused." + } + }, + "questions/approved_firms/permit-application-sent.yaml": { + "question": "What happens now?", + "description": "It has reached our case officers.", + "next_heading": "We read it and come back to you", + "next_description": "Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example.", + "back": "Back", + "see_all": { + "heading": "See all applications", + "description": "", + "button": "Open" + } + }, + "questions/approved_firms/permit-application.yaml": { + "heading": "a decision inside twelve weeks, and to know when the clock stops", + "description": "For an approved firm filing on behalf of an owner.", + "button": "Send", + "encouragement": "", + "icon": "", + "requires_title": "", + "requires_description": "", + "requires_icon": "", + "road_title": "What happens next", + "road_description": "It is open, then papers missing, then papers complete, then out to the neighbours and the agencies, then recommendation written, and ends approved, approved on conditions, refused or withdrawn.", + "road_icon": "route", + "who_title": "Who reads it", + "who_description": "Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example.", + "who_icon": "users", + "form_title": "Details", + "form_description": "", + "labels": { + "email": "Email", + "property_address": "Property address", + "property_number": "Property number", + "what_is_planned": "What is planned", + "neighbours_notified": "Neighbours notified", + "site": "Site", + "drawings_url": "Drawings url" + }, + "hints": { + "email": "", + "property_address": "", + "property_number": "", + "what_is_planned": "", + "neighbours_notified": "", + "site": "", + "drawings_url": "" + }, + "question": "Permit application?", + "page_description": "" + }, + "questions/building-near-me/index.yaml": { + "question": "What do you need?", + "description": "For someone who lives next to what is being built.", + "needs": { + "objection": { + "heading": "what they think on the record, and answered in the decision", + "description": "For a neighbour who got a notice about what is planned next door.", + "button": "Send", + "encouragement": "", + "icon": "", + "requires_title": "What you need", + "requires_description": "The notice that came in the post, which has the case number on it.", + "requires_icon": "key", + "road_title": "What happens next", + "road_description": "It is open, then on the case file, then the applicant has answered, and ends answered in the decision or withdrawn.", + "road_icon": "route", + "who_title": "Who reads it", + "who_description": "Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example.", + "who_icon": "users", + "form_title": "Details", + "form_description": "", + "labels": { + "email": "Email", + "case_number": "Case number", + "your_property": "Your property", + "your_objection": "Your objection" + }, + "hints": { + "email": "", + "case_number": "", + "your_property": "", + "your_objection": "" + } + }, + "case-status-enquiry": { + "heading": "to be told where it actually stands", + "description": "For someone waiting on a case and getting nothing back.", + "button": "Send", + "encouragement": "", + "icon": "", + "requires_title": "", + "requires_description": "", + "requires_icon": "", + "road_title": "What happens next", + "road_description": "It is open, then in hand, and ends answered.", + "road_icon": "route", + "who_title": "Who reads it", + "who_description": "Front desk. Questions go to Solveig Hauge at byggesak@vestmark.example.", + "who_icon": "users", + "form_title": "Details", + "form_description": "", + "labels": { + "email": "Email", + "case_number_or_address": "Case number or address", + "what_you_want_to_know": "What you want to know" + }, + "hints": { + "email": "", + "case_number_or_address": "", + "what_you_want_to_know": "" + } + }, + "illegal-building-report": { + "heading": "us to go and look, and to hear that we did", + "description": "For someone who can see building going up that nobody was told about.", + "button": "Send", + "encouragement": "", + "icon": "", + "requires_title": "", + "requires_description": "", + "requires_icon": "", + "road_title": "What happens next", + "road_description": "It is open, then inspected, then the owner has been written to, then the owner has answered, and ends resolved, fined or nothing to pursue.", + "road_icon": "route", + "who_title": "Who reads it", + "who_description": "Inspectors. Questions go to Solveig Hauge at byggesak@vestmark.example.", + "who_icon": "users", + "form_title": "Details", + "form_description": "", + "labels": { + "email": "Email", + "address": "Address", + "what_you_saw": "What you saw", + "where": "Where" + }, + "hints": { + "email": "", + "address": "", + "what_you_saw": "", + "where": "" + } + } + } + }, + "questions/case_officers/index.yaml": { + "question": "What needs doing?", + "description": "Everything case officers looks after.", + "confirm": "Confirm", + "buckets": { + "appeals": { + "heading": "Appeals", + "description": "Sent in by anyone with an interest who will not accept a decision of ours.", + "moves": { + "open->reconsidered": "We are looking at it again" + }, + "list_title": "Appeals", + "list_note": "Each row is one case. The buttons record what you have just done with it." + }, + "applications": { + "heading": "Applications", + "description": "Sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner.", + "moves": { + "complete->on_hearing": "Out to the neighbours and the agencies", + "complete->incomplete": "Papers missing", + "incomplete->complete": "Papers complete", + "on_hearing->recommended": "Recommendation written", + "on_hearing->incomplete": "Papers missing", + "open->complete": "Papers complete", + "open->incomplete": "Papers missing" + }, + "list_title": "Applications", + "list_note": "Each row is one case. The buttons record what you have just done with it." + }, + "completions": { + "heading": "Completions", + "description": "Sent in by an owner or firm whose building work is finished.", + "moves": { + "open->checked": "Checked against the inspections" + }, + "list_title": "Completions", + "list_note": "Each row is one case. The buttons record what you have just done with it." + }, + "enquiries": { + "heading": "Enquiries", + "description": "Sent in by someone waiting on a case and getting nothing back or whoever is on the counter with a queue and a caller on the line.", + "moves": { + "open->in_hand": "In hand" + }, + "list_title": "Enquiries", + "list_note": "Each row is one case. The buttons record what you have just done with it." + }, + "exemptions": { + "heading": "Exemptions", + "description": "Sent in by someone whose plans break a rule in the zoning map.", + "moves": { + "county_answered->recommended": "Recommended", + "open->county_asked": "With the county" + }, + "list_title": "Exemptions", + "list_note": "Each row is one case. The buttons record what you have just done with it." + }, + "firms": { + "heading": "Firms", + "description": "Sent in by an architect or engineering firm that files for its clients.", + "moves": { + "open->papers_missing": "Waiting on papers", + "open->checked": "Papers checked", + "papers_missing->checked": "Papers checked" + }, + "list_title": "Firms", + "list_note": "Each row is one case. The buttons record what you have just done with it." + }, + "hearing_answers": { + "heading": "Hearing answers", + "description": "Sent in by a road, fire, heritage or county officer who has been asked about a case.", + "moves": { + "open->read": "Read by the case officer", + "open->set_aside": "Set aside with reasons", + "read->followed": "Followed in the decision", + "read->set_aside": "Set aside with reasons" + }, + "list_title": "Hearing answers", + "list_note": "Each row is one case. The buttons record what you have just done with it." + }, + "hearings": { + "heading": "Hearings", + "description": "Sent in by a case officer sending a case out to the authority that must see it.", + "moves": { + "open->no_answer": "The deadline passed with no answer", + "open->cancelled": "Cancelled" + }, + "list_title": "Hearings", + "list_note": "Each row is one case. The buttons record what you have just done with it." + }, + "illegal_building": { + "heading": "Illegal building", + "description": "Sent in by someone who can see building going up that nobody was told about.", + "moves": { + "inspected->owner_asked": "The owner has been written to", + "owner_asked->explained": "The owner has answered" + }, + "list_title": "Illegal building", + "list_note": "Each row is one case. The buttons record what you have just done with it." + }, + "inspections": { + "heading": "Inspections", + "description": "Sent in by an inspector on a scaffold with gloves on and the wind blowing.", + "moves": { + "deviation->escalated": "Handed to a case officer", + "open->escalated": "Handed to a case officer" + }, + "list_title": "Inspections", + "list_note": "Each row is one case. The buttons record what you have just done with it." + }, + "meetings": { + "heading": "Meetings", + "description": "Sent in by someone with an idea for a building and no drawings yet.", + "moves": { + "met->advised": "Written advice sent", + "open->scheduled": "Scheduled", + "scheduled->met": "We have met" + }, + "list_title": "Meetings", + "list_note": "Each row is one case. The buttons record what you have just done with it." + }, + "objections": { + "heading": "Objections", + "description": "Sent in by a neighbour who got a notice about what is planned next door.", + "moves": { + "answered_by_applicant->addressed": "Answered in the decision", + "open->registered": "On the case file", + "registered->answered_by_applicant": "The applicant has answered" + }, + "list_title": "Objections", + "list_note": "Each row is one case. The buttons record what you have just done with it." + } + }, + "links": { + "request-hearing": { + "heading": "an answer by the deadline, or a record that none came", + "description": "For a case officer sending a case out to the authority that must see it.", + "button": "Open" + } + }, + "invites": { + "agencies": { + "heading": "Invite someone into Hearing bodies", + "description": "They get an account, a place in Hearing bodies, and a one-time link to set their own password or passkey.", + "button": "Invite", + "form_title": "Who", + "form_description": "Their name, and the address the account and its one-time link go to.", + "labels": { + "name": "Name", + "email": "Email" + } + }, + "appeals_board": { + "heading": "Invite someone into Appeals board", + "description": "They get an account, a place in Appeals board, and a one-time link to set their own password or passkey.", + "button": "Invite", + "form_title": "Who", + "form_description": "Their name, and the address the account and its one-time link go to.", + "labels": { + "name": "Name", + "email": "Email" + } + }, + "approved_firms": { + "heading": "Invite someone into Approved firms", + "description": "They get an account, a place in Approved firms, and a one-time link to set their own password or passkey.", + "button": "Invite", + "form_title": "Who", + "form_description": "Their name, and the address the account and its one-time link go to.", + "labels": { + "name": "Name", + "email": "Email" + } + }, + "case_officers": { + "heading": "Invite someone into Case officers", + "description": "They get an account, a place in Case officers, and a one-time link to set their own password or passkey.", + "button": "Invite", + "form_title": "Who", + "form_description": "Their name, and the address the account and its one-time link go to.", + "labels": { + "name": "Name", + "email": "Email" + } + }, + "front_desk": { + "heading": "Invite someone into Front desk", + "description": "They get an account, a place in Front desk, and a one-time link to set their own password or passkey.", + "button": "Invite", + "form_title": "Who", + "form_description": "Their name, and the address the account and its one-time link go to.", + "labels": { + "name": "Name", + "email": "Email" + } + }, + "inspectors": { + "heading": "Invite someone into Inspectors", + "description": "They get an account, a place in Inspectors, and a one-time link to set their own password or passkey.", + "button": "Invite", + "form_title": "Who", + "form_description": "Their name, and the address the account and its one-time link go to.", + "labels": { + "name": "Name", + "email": "Email" + } + }, + "section_head": { + "heading": "Invite someone into Head of section", + "description": "They get an account, a place in Head of section, and a one-time link to set their own password or passkey.", + "button": "Invite", + "form_title": "Who", + "form_description": "Their name, and the address the account and its one-time link go to.", + "labels": { + "name": "Name", + "email": "Email" + } + } + }, + "invited": { + "heading": "Invitations sent", + "description": "Each invite with the link it made. Mark it done when the person is in.", + "done": "Is in", + "list_title": "Who has been invited", + "list_note": "Each row is one invitation, with the one-time link while it is unused." + } + }, + "questions/case_officers/request-hearing-sent.yaml": { + "question": "What happens now?", + "description": "It has reached our case officers.", + "next_heading": "We read it and come back to you", + "next_description": "Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example.", + "back": "Back" + }, + "questions/case_officers/request-hearing.yaml": { + "heading": "an answer by the deadline, or a record that none came", + "description": "For a case officer sending a case out to the authority that must see it.", + "button": "Send", + "encouragement": "", + "icon": "", + "requires_title": "", + "requires_description": "", + "requires_icon": "", + "road_title": "What happens next", + "road_description": "It is open, and ends answered, the deadline passed with no answer or cancelled.", + "road_icon": "route", + "who_title": "Who reads it", + "who_description": "Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example.", + "who_icon": "users", + "form_title": "Details", + "form_description": "", + "labels": { + "case_number": "Case number", + "which_authority": "Which authority", + "what_we_ask": "What we ask", + "answer_by": "Answer by", + "site": "Site" + }, + "hints": { + "case_number": "", + "which_authority": "", + "what_we_ask": "", + "answer_by": "", + "site": "" + }, + "question": "Request hearing?", + "page_description": "" + }, + "questions/decide/appeal.yaml": { + "question": "What would you like to do?", + "description": "", + "moves": { + "withdrawn": { + "heading": "Withdrawn", + "description": "", + "button": "Withdrawn" + } + } + }, + "questions/decide/exemption-request.yaml": { + "question": "What would you like to do?", + "description": "", + "moves": { + "withdrawn": { + "heading": "Withdrawn", + "description": "", + "button": "Withdrawn" + } + } + }, + "questions/decide/firm-approval.yaml": { + "question": "What would you like to do?", + "description": "", + "moves": { + "checked": { + "heading": "Checked", + "description": "", + "button": "Checked" + } + } + }, + "questions/decide/objection.yaml": { + "question": "What would you like to do?", + "description": "", + "moves": { + "withdrawn": { + "heading": "Withdrawn", + "description": "", + "button": "Withdrawn" + } + } + }, + "questions/decide/permit-application.yaml": { + "question": "What would you like to do?", + "description": "", + "moves": { + "complete": { + "heading": "Complete", + "description": "", + "button": "Complete" + }, + "withdrawn": { + "heading": "Withdrawn", + "description": "", + "button": "Withdrawn" + } + } + }, + "questions/decide/pre-application-meeting.yaml": { + "question": "What would you like to do?", + "description": "", + "moves": { + "cancelled": { + "heading": "Cancelled", + "description": "", + "button": "Cancelled" + } + } + }, + "questions/decide/small-works-application.yaml": { + "question": "What would you like to do?", + "description": "", + "moves": { + "complete": { + "heading": "Complete", + "description": "", + "button": "Complete" + }, + "withdrawn": { + "heading": "Withdrawn", + "description": "", + "button": "Withdrawn" + } + } + }, + "questions/front_desk/index.yaml": { + "question": "What needs doing?", + "description": "Everything front desk looks after.", + "confirm": "Confirm", + "buckets": { + "appeals": { + "heading": "Appeals", + "description": "Sent in by anyone with an interest who will not accept a decision of ours.", + "moves": {}, + "list_title": "Appeals", + "list_note": "Each row is one case and the stage it has reached. Another desk moves these." + }, + "applications": { + "heading": "Applications", + "description": "Sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner.", + "moves": {}, + "list_title": "Applications", + "list_note": "Each row is one case and the stage it has reached. Another desk moves these." + }, + "enquiries": { + "heading": "Enquiries", + "description": "Sent in by someone waiting on a case and getting nothing back or whoever is on the counter with a queue and a caller on the line.", + "moves": { + "in_hand->answered": "Answered", + "open->in_hand": "In hand" + }, + "list_title": "Enquiries", + "list_note": "Each row is one case. The buttons record what you have just done with it." + }, + "firms": { + "heading": "Firms", + "description": "Sent in by an architect or engineering firm that files for its clients.", + "moves": {}, + "list_title": "Firms", + "list_note": "Each row is one case and the stage it has reached. Another desk moves these." + }, + "hearing_answers": { + "heading": "Hearing answers", + "description": "Sent in by a road, fire, heritage or county officer who has been asked about a case.", + "moves": {}, + "list_title": "Hearing answers", + "list_note": "Each row is one case and the stage it has reached. Another desk moves these." + }, + "hearings": { + "heading": "Hearings", + "description": "Sent in by a case officer sending a case out to the authority that must see it.", + "moves": {}, + "list_title": "Hearings", + "list_note": "Each row is one case and the stage it has reached. Another desk moves these." + }, + "meetings": { + "heading": "Meetings", + "description": "Sent in by someone with an idea for a building and no drawings yet.", + "moves": { + "met->cancelled": "Cancelled", + "open->cancelled": "Cancelled", + "scheduled->cancelled": "Cancelled" + }, + "list_title": "Meetings", + "list_note": "Each row is one case. The buttons record what you have just done with it." + } + }, + "links": { + "log-counter-enquiry": { + "heading": "the question written down and sent to whoever has the case", + "description": "For whoever is on the counter with a queue and a caller on the line.", + "button": "Open" + } + }, + "invites": { + "front_desk": { + "heading": "Invite someone into Front desk", + "description": "They get an account, a place in Front desk, and a one-time link to set their own password or passkey.", + "button": "Invite", + "form_title": "Who", + "form_description": "Their name, and the address the account and its one-time link go to.", + "labels": { + "name": "Name", + "email": "Email" + } + } + }, + "invited": { + "heading": "Invitations sent", + "description": "Each invite with the link it made. Mark it done when the person is in.", + "done": "Is in", + "list_title": "Who has been invited", + "list_note": "Each row is one invitation, with the one-time link while it is unused." + } + }, + "questions/front_desk/log-counter-enquiry-sent.yaml": { + "question": "What happens now?", + "description": "It has reached our front desk.", + "next_heading": "We read it and come back to you", + "next_description": "Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example.", + "back": "Back" + }, + "questions/front_desk/log-counter-enquiry.yaml": { + "heading": "the question written down and sent to whoever has the case", + "description": "For whoever is on the counter with a queue and a caller on the line.", + "button": "Send", + "encouragement": "", + "icon": "", + "requires_title": "", + "requires_description": "", + "requires_icon": "", + "road_title": "What happens next", + "road_description": "It is open, then in hand, and ends answered.", + "road_icon": "route", + "who_title": "Who reads it", + "who_description": "Front desk. Questions go to Solveig Hauge at byggesak@vestmark.example.", + "who_icon": "users", + "form_title": "Details", + "form_description": "", + "labels": { + "email": "Email", + "case_number_or_address": "Case number or address", + "what_you_want_to_know": "What you want to know" + }, + "hints": { + "email": "", + "case_number_or_address": "", + "what_you_want_to_know": "" + }, + "question": "Log counter enquiry?", + "page_description": "" + }, + "questions/index.yaml": { + "question": "What brings you here?", + "description": "The building authority for twenty-one thousand people. Anything built, demolished, divided or changed in use is decided here: the drawings are checked against the zoning map, the neighbours and the other authorities have their say, and then the head of section signs. The same office inspects what is actually built, signs off finished work, and deals with building nobody applied for.\n", + "opener": { + "heading": "What we do", + "description": "", + "features": { + "we-decide-what-may-be-built": { + "heading": "Permission to build it, and to know where the case stands", + "description": "Everything built in Vestmark is decided here. You send the drawings, the neighbours and the road, fire and heritage authorities are heard, and you get a written decision you can hold us to.\n", + "icon": "" + }, + "your-neighbours-case-is-readable": { + "heading": "What they think on the record, and answered in the decision", + "description": "If a notice landed in your postbox, the case behind it is open to read here, and what you write to us has to be answered by name in the decision.\n", + "icon": "" + } + } + }, + "shopping": { + "heading": "Have a look around", + "description": "", + "items": { + "status-appeals": { + "heading": "See all appeals", + "description": "Everything sent in by anyone with an interest who will not accept a decision of ours, and where each one stands.", + "icon": "list" + }, + "status-applications": { + "heading": "See all applications", + "description": "Everything sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner, and where each one stands.", + "icon": "list" + }, + "status-completions": { + "heading": "See all completions", + "description": "Everything sent in by an owner or firm whose building work is finished, and where each one stands.", + "icon": "list" + }, + "status-exemptions": { + "heading": "See all exemptions", + "description": "Everything sent in by someone whose plans break a rule in the zoning map, and where each one stands.", + "icon": "list" + }, + "status-objections": { + "heading": "See all objections", + "description": "Everything sent in by a neighbour who got a notice about what is planned next door, and where each one stands.", + "icon": "list" + } + } + }, + "doors": { + "want-to-build": { + "heading": "Want to build", + "description": "For an owner or a firm with something to build, divide or change.", + "button": "Continue", + "icon": "", + "for_whom": "", + "behind": "To hear what we will allow before paying an architect, permission to build it, and to know where the case stands, to be allowed it anyway, with reasons on the record, the certificate that lets the building be used." + }, + "building-near-me": { + "heading": "Building near me", + "description": "For someone who lives next to what is being built.", + "button": "Continue", + "icon": "", + "for_whom": "", + "behind": "What they think on the record, and answered in the decision, to be told where it actually stands, us to go and look, and to hear that we did." + } + }, + "needs": { + "appeal": { + "heading": "the decision looked at again, by us and then by the board", + "description": "For anyone with an interest who will not accept a decision of ours.", + "button": "Send", + "encouragement": "", + "icon": "", + "requires_title": "What you need", + "requires_description": "A decision from us less than three weeks old, and its case number.", + "requires_icon": "key", + "road_title": "What happens next", + "road_description": "It is open, then we are looking at it again, then with the appeals board, and ends we changed our own decision, the board kept our decision, the board overturned us or withdrawn.", + "road_icon": "route", + "who_title": "Who reads it", + "who_description": "Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example.", + "who_icon": "users", + "form_title": "Details", + "form_description": "", + "labels": { + "email": "Email", + "case_number": "Case number", + "property": "Property", + "what_you_disagree_with": "What you disagree with", + "your_interest": "Your interest" + }, + "hints": { + "email": "", + "case_number": "", + "property": "", + "what_you_disagree_with": "", + "your_interest": "" + } + }, + "firm-approval": { + "heading": "to be on the list, and then to file without asking again", + "description": "For an architect or engineering firm that files for its clients.", + "button": "Send", + "encouragement": "", + "icon": "", + "requires_title": "", + "requires_description": "", + "requires_icon": "", + "road_title": "What happens next", + "road_description": "It is open, then waiting on papers, then papers checked, and ends approved or declined.", + "road_icon": "route", + "who_title": "Who reads it", + "who_description": "Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example.", + "who_icon": "users", + "form_title": "Details", + "form_description": "", + "labels": { + "firm_name": "Firm name", + "org_number": "Org number", + "email": "Email", + "qualified_for": "Qualified for", + "insurance_expires": "Insurance expires", + "insurance_document": "Insurance document" + }, + "hints": { + "firm_name": "", + "org_number": "", + "email": "", + "qualified_for": "", + "insurance_expires": "", + "insurance_document": "" + } + } + } + }, + "questions/inspectors/index.yaml": { + "question": "What needs doing?", + "description": "Everything inspectors looks after.", + "confirm": "Confirm", + "buckets": { + "applications": { + "heading": "Applications", + "description": "Sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner.", + "moves": {}, + "list_title": "Applications", + "list_note": "Each row is one case and the stage it has reached. Another desk moves these." + }, + "completions": { + "heading": "Completions", + "description": "Sent in by an owner or firm whose building work is finished.", + "moves": {}, + "list_title": "Completions", + "list_note": "Each row is one case and the stage it has reached. Another desk moves these." + }, + "illegal_building": { + "heading": "Illegal building", + "description": "Sent in by someone who can see building going up that nobody was told about.", + "moves": { + "explained->resolved": "Resolved", + "explained->dropped": "Nothing to pursue", + "open->inspected": "Inspected" + }, + "list_title": "Illegal building", + "list_note": "Each row is one case. The buttons record what you have just done with it." + }, + "inspections": { + "heading": "Inspections", + "description": "Sent in by an inspector on a scaffold with gloves on and the wind blowing.", + "moves": { + "deviation->as_approved": "Built as approved", + "deviation->put_right": "Put right", + "open->deviation": "Built differently" + }, + "list_title": "Inspections", + "list_note": "Each row is one case. The buttons record what you have just done with it." + } + }, + "links": { + "inspection-finding": { + "heading": "what they found logged before they climb down", + "description": "For an inspector on a scaffold with gloves on and the wind blowing.", + "button": "Open" + } + }, + "invites": { + "inspectors": { + "heading": "Invite someone into Inspectors", + "description": "They get an account, a place in Inspectors, and a one-time link to set their own password or passkey.", + "button": "Invite", + "form_title": "Who", + "form_description": "Their name, and the address the account and its one-time link go to.", + "labels": { + "name": "Name", + "email": "Email" + } + } + }, + "invited": { + "heading": "Invitations sent", + "description": "Each invite with the link it made. Mark it done when the person is in.", + "done": "Is in", + "list_title": "Who has been invited", + "list_note": "Each row is one invitation, with the one-time link while it is unused." + } + }, + "questions/inspectors/inspection-finding-sent.yaml": { + "question": "What happens now?", + "description": "It has reached our inspectors.", + "next_heading": "We read it and come back to you", + "next_description": "Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example.", + "back": "Back" + }, + "questions/inspectors/inspection-finding.yaml": { + "heading": "what they found logged before they climb down", + "description": "For an inspector on a scaffold with gloves on and the wind blowing.", + "button": "Send", + "encouragement": "", + "icon": "", + "requires_title": "", + "requires_description": "", + "requires_icon": "", + "road_title": "What happens next", + "road_description": "It is open, then built differently, and ends built as approved, put right or handed to a case officer.", + "road_icon": "route", + "who_title": "Who reads it", + "who_description": "Inspectors. Questions go to Solveig Hauge at byggesak@vestmark.example.", + "who_icon": "users", + "form_title": "Details", + "form_description": "", + "labels": { + "case_number": "Case number", + "site_address": "Site address", + "what_i_found": "What i found", + "where": "Where" + }, + "hints": { + "case_number": "", + "site_address": "", + "what_i_found": "", + "where": "" + }, + "question": "Inspection finding?", + "page_description": "" + }, + "questions/received/appeal.yaml": { + "question": "What happens now?", + "description": "It has reached our case officers.", + "next_heading": "We read it and come back to you", + "next_description": "Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example.", + "back": "Back", + "see_all": { + "heading": "See all appeals", + "description": "", + "button": "Open" + } + }, + "questions/received/case-status-enquiry.yaml": { + "question": "What happens now?", + "description": "It has reached our front desk.", + "next_heading": "We read it and come back to you", + "next_description": "Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example.", + "back": "Back" + }, + "questions/received/completion-request.yaml": { + "question": "What happens now?", + "description": "It has reached our case officers.", + "next_heading": "We read it and come back to you", + "next_description": "Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example.", + "back": "Back", + "see_all": { + "heading": "See all completions", + "description": "", + "button": "Open" + } + }, + "questions/received/exemption-request.yaml": { + "question": "What happens now?", + "description": "It has reached our case officers.", + "next_heading": "We read it and come back to you", + "next_description": "Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example.", + "back": "Back", + "see_all": { + "heading": "See all exemptions", + "description": "", + "button": "Open" + } + }, + "questions/received/firm-approval.yaml": { + "question": "What happens now?", + "description": "It has reached our case officers.", + "next_heading": "We read it and come back to you", + "next_description": "Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example.", + "back": "Back" + }, + "questions/received/illegal-building-report.yaml": { + "question": "What happens now?", + "description": "It has reached our inspectors.", + "next_heading": "We read it and come back to you", + "next_description": "Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example.", + "back": "Back" + }, + "questions/received/objection.yaml": { + "question": "What happens now?", + "description": "It has reached our case officers.", + "next_heading": "We read it and come back to you", + "next_description": "Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example.", + "back": "Back", + "see_all": { + "heading": "See all objections", + "description": "", + "button": "Open" + } + }, + "questions/received/pre-application-meeting.yaml": { + "question": "What happens now?", + "description": "It has reached our case officers.", + "next_heading": "We read it and come back to you", + "next_description": "Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example.", + "back": "Back" + }, + "questions/received/small-works-application.yaml": { + "question": "What happens now?", + "description": "It has reached our case officers.", + "next_heading": "We read it and come back to you", + "next_description": "Questions in the meantime go to Solveig Hauge at byggesak@vestmark.example.", + "back": "Back", + "see_all": { + "heading": "See all applications", + "description": "", + "button": "Open" + } + }, + "questions/section_head/index.yaml": { + "question": "What needs doing?", + "description": "Everything head of section looks after.", + "confirm": "Confirm", + "buckets": { + "appeals": { + "heading": "Appeals", + "description": "Sent in by anyone with an interest who will not accept a decision of ours.", + "moves": { + "reconsidered->before_the_board": "With the appeals board", + "reconsidered->changed_by_us": "We changed our own decision" + }, + "list_title": "Appeals", + "list_note": "Each row is one case. The buttons record what you have just done with it." + }, + "applications": { + "heading": "Applications", + "description": "Sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner.", + "moves": { + "complete->refused": "Refused", + "on_hearing->refused": "Refused", + "recommended->approved": "Approved", + "recommended->approved_with_conditions": "Approved on conditions", + "recommended->refused": "Refused" + }, + "list_title": "Applications", + "list_note": "Each row is one case. The buttons record what you have just done with it." + }, + "completions": { + "heading": "Completions", + "description": "Sent in by an owner or firm whose building work is finished.", + "moves": { + "checked->temporary_permission": "Temporary permission to use", + "checked->certificate_issued": "Certificate issued", + "checked->refused": "Refused", + "open->refused": "Refused", + "temporary_permission->certificate_issued": "Certificate issued" + }, + "list_title": "Completions", + "list_note": "Each row is one case. The buttons record what you have just done with it." + }, + "exemptions": { + "heading": "Exemptions", + "description": "Sent in by someone whose plans break a rule in the zoning map.", + "moves": { + "county_answered->denied": "Denied", + "county_asked->denied": "Denied", + "open->denied": "Denied", + "recommended->granted": "Granted", + "recommended->denied": "Denied" + }, + "list_title": "Exemptions", + "list_note": "Each row is one case. The buttons record what you have just done with it." + }, + "firms": { + "heading": "Firms", + "description": "Sent in by an architect or engineering firm that files for its clients.", + "moves": { + "checked->approved": "Approved", + "checked->declined": "Declined", + "open->declined": "Declined", + "papers_missing->declined": "Declined" + }, + "list_title": "Firms", + "list_note": "Each row is one case. The buttons record what you have just done with it." + }, + "hearing_answers": { + "heading": "Hearing answers", + "description": "Sent in by a road, fire, heritage or county officer who has been asked about a case.", + "moves": {}, + "list_title": "Hearing answers", + "list_note": "Each row is one case and the stage it has reached. Another desk moves these." + }, + "hearings": { + "heading": "Hearings", + "description": "Sent in by a case officer sending a case out to the authority that must see it.", + "moves": {}, + "list_title": "Hearings", + "list_note": "Each row is one case and the stage it has reached. Another desk moves these." + }, + "illegal_building": { + "heading": "Illegal building", + "description": "Sent in by someone who can see building going up that nobody was told about.", + "moves": { + "inspected->fined": "Fined", + "open->fined": "Fined" + }, + "list_title": "Illegal building", + "list_note": "Each row is one case. The buttons record what you have just done with it." + }, + "inspections": { + "heading": "Inspections", + "description": "Sent in by an inspector on a scaffold with gloves on and the wind blowing.", + "moves": { + "deviation->escalated": "Handed to a case officer", + "open->escalated": "Handed to a case officer" + }, + "list_title": "Inspections", + "list_note": "Each row is one case. The buttons record what you have just done with it." + }, + "objections": { + "heading": "Objections", + "description": "Sent in by a neighbour who got a notice about what is planned next door.", + "moves": {}, + "list_title": "Objections", + "list_note": "Each row is one case and the stage it has reached. Another desk moves these." + } + }, + "links": {}, + "invites": { + "agencies": { + "heading": "Invite someone into Hearing bodies", + "description": "They get an account, a place in Hearing bodies, and a one-time link to set their own password or passkey.", + "button": "Invite", + "form_title": "Who", + "form_description": "Their name, and the address the account and its one-time link go to.", + "labels": { + "name": "Name", + "email": "Email" + } + }, + "appeals_board": { + "heading": "Invite someone into Appeals board", + "description": "They get an account, a place in Appeals board, and a one-time link to set their own password or passkey.", + "button": "Invite", + "form_title": "Who", + "form_description": "Their name, and the address the account and its one-time link go to.", + "labels": { + "name": "Name", + "email": "Email" + } + }, + "approved_firms": { + "heading": "Invite someone into Approved firms", + "description": "They get an account, a place in Approved firms, and a one-time link to set their own password or passkey.", + "button": "Invite", + "form_title": "Who", + "form_description": "Their name, and the address the account and its one-time link go to.", + "labels": { + "name": "Name", + "email": "Email" + } + }, + "case_officers": { + "heading": "Invite someone into Case officers", + "description": "They get an account, a place in Case officers, and a one-time link to set their own password or passkey.", + "button": "Invite", + "form_title": "Who", + "form_description": "Their name, and the address the account and its one-time link go to.", + "labels": { + "name": "Name", + "email": "Email" + } + }, + "front_desk": { + "heading": "Invite someone into Front desk", + "description": "They get an account, a place in Front desk, and a one-time link to set their own password or passkey.", + "button": "Invite", + "form_title": "Who", + "form_description": "Their name, and the address the account and its one-time link go to.", + "labels": { + "name": "Name", + "email": "Email" + } + }, + "inspectors": { + "heading": "Invite someone into Inspectors", + "description": "They get an account, a place in Inspectors, and a one-time link to set their own password or passkey.", + "button": "Invite", + "form_title": "Who", + "form_description": "Their name, and the address the account and its one-time link go to.", + "labels": { + "name": "Name", + "email": "Email" + } + }, + "section_head": { + "heading": "Invite someone into Head of section", + "description": "They get an account, a place in Head of section, and a one-time link to set their own password or passkey.", + "button": "Invite", + "form_title": "Who", + "form_description": "Their name, and the address the account and its one-time link go to.", + "labels": { + "name": "Name", + "email": "Email" + } + } + }, + "invited": { + "heading": "Invitations sent", + "description": "Each invite with the link it made. Mark it done when the person is in.", + "done": "Is in", + "list_title": "Who has been invited", + "list_note": "Each row is one invitation, with the one-time link while it is unused." + } + }, + "questions/status/appeals/index.yaml": { + "question": "What has been sent in about appeals?", + "description": "Everything sent in by anyone with an interest who will not accept a decision of ours, and where each one stands.", + "heading": "Appeals", + "list_description": "", + "list_title": "Appeals", + "list_note": "Each row is one case and the stage it has reached. Names and contact details are not shown here.", + "back": "Back" + }, + "questions/status/applications/index.yaml": { + "question": "What has been sent in about applications?", + "description": "Everything sent in by an owner applying for something small enough to file themselves or an approved firm filing on behalf of an owner, and where each one stands.", + "heading": "Applications", + "list_description": "", + "list_title": "Applications", + "list_note": "Each row is one case and the stage it has reached. Names and contact details are not shown here.", + "back": "Back" + }, + "questions/status/completions/index.yaml": { + "question": "What has been sent in about completions?", + "description": "Everything sent in by an owner or firm whose building work is finished, and where each one stands.", + "heading": "Completions", + "list_description": "", + "list_title": "Completions", + "list_note": "Each row is one case and the stage it has reached. Names and contact details are not shown here.", + "back": "Back" + }, + "questions/status/exemptions/index.yaml": { + "question": "What has been sent in about exemptions?", + "description": "Everything sent in by someone whose plans break a rule in the zoning map, and where each one stands.", + "heading": "Exemptions", + "list_description": "", + "list_title": "Exemptions", + "list_note": "Each row is one case and the stage it has reached. Names and contact details are not shown here.", + "back": "Back" + }, + "questions/status/objections/index.yaml": { + "question": "What has been sent in about objections?", + "description": "Everything sent in by a neighbour who got a notice about what is planned next door, and where each one stands.", + "heading": "Objections", + "list_description": "", + "list_title": "Objections", + "list_note": "Each row is one case and the stage it has reached. Names and contact details are not shown here.", + "back": "Back" + }, + "questions/want-to-build/index.yaml": { + "question": "What do you need?", + "description": "For an owner or a firm with something to build, divide or change.", + "needs": { + "pre-application-meeting": { + "heading": "to hear what we will allow before paying an architect", + "description": "For someone with an idea for a building and no drawings yet.", + "button": "Send", + "encouragement": "", + "icon": "", + "requires_title": "", + "requires_description": "", + "requires_icon": "", + "road_title": "What happens next", + "road_description": "It is open, then scheduled, then we have met, and ends written advice sent or cancelled.", + "road_icon": "route", + "who_title": "Who reads it", + "who_description": "Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example.", + "who_icon": "users", + "form_title": "Details", + "form_description": "", + "labels": { + "name": "Name", + "email": "Email", + "property_address": "Property address", + "what_you_want": "What you want", + "phone": "Phone", + "site": "Site" + }, + "hints": { + "name": "", + "email": "", + "property_address": "", + "what_you_want": "", + "phone": "", + "site": "" + } + }, + "small-works-application": { + "heading": "permission to build it, and to know where the case stands", + "description": "For an owner applying for something small enough to file themselves.", + "button": "Send", + "encouragement": "", + "icon": "", + "requires_title": "", + "requires_description": "", + "requires_icon": "", + "road_title": "What happens next", + "road_description": "It is open, then papers missing, then papers complete, then out to the neighbours and the agencies, then recommendation written, and ends approved, approved on conditions, refused or withdrawn.", + "road_icon": "route", + "who_title": "Who reads it", + "who_description": "Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example.", + "who_icon": "users", + "form_title": "Details", + "form_description": "", + "labels": { + "email": "Email", + "property_address": "Property address", + "property_number": "Property number", + "what_is_planned": "What is planned", + "neighbours_notified": "Neighbours notified", + "site": "Site", + "drawings_url": "Drawings url" + }, + "hints": { + "email": "", + "property_address": "", + "property_number": "", + "what_is_planned": "", + "neighbours_notified": "", + "site": "", + "drawings_url": "" + } + }, + "exemption-request": { + "heading": "to be allowed it anyway, with reasons on the record", + "description": "For someone whose plans break a rule in the zoning map.", + "button": "Send", + "encouragement": "", + "icon": "", + "requires_title": "What you need", + "requires_description": "An application already with us, and the case number from its receipt.", + "requires_icon": "key", + "road_title": "What happens next", + "road_description": "It is open, then with the county, then the county has answered, then recommended, and ends granted, denied or withdrawn.", + "road_icon": "route", + "who_title": "Who reads it", + "who_description": "Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example.", + "who_icon": "users", + "form_title": "Details", + "form_description": "", + "labels": { + "email": "Email", + "case_number": "Case number", + "which_rule": "Which rule", + "why_it_should_be_allowed": "Why it should be allowed", + "site": "Site" + }, + "hints": { + "email": "", + "case_number": "", + "which_rule": "", + "why_it_should_be_allowed": "", + "site": "" + } + }, + "completion-request": { + "heading": "the certificate that lets the building be used", + "description": "For an owner or firm whose building work is finished.", + "button": "Send", + "encouragement": "", + "icon": "", + "requires_title": "What you need", + "requires_description": "A case number, and the work finished or close enough to move in.", + "requires_icon": "key", + "road_title": "What happens next", + "road_description": "It is open, then checked against the inspections, then temporary permission to use, and ends certificate issued or refused.", + "road_icon": "route", + "who_title": "Who reads it", + "who_description": "Case officers. Questions go to Solveig Hauge at byggesak@vestmark.example.", + "who_icon": "users", + "form_title": "Details", + "form_description": "", + "labels": { + "email": "Email", + "case_number": "Case number", + "property_address": "Property address", + "work_finished": "Work finished", + "asking_for": "Asking for", + "what_is_outstanding": "What is outstanding" + }, + "hints": { + "email": "", + "case_number": "", + "property_address": "", + "work_finished": "", + "asking_for": "", + "what_is_outstanding": "" + } + } + } + } +} \ No newline at end of file diff --git a/src/build.rs b/src/build.rs index 4588793..5dfc9b5 100644 --- a/src/build.rs +++ b/src/build.rs @@ -196,6 +196,18 @@ pub struct PlanNeed { /// start and not after, where they depart instead. #[serde(default)] pub turned_down_from: Vec, + /// Where a stage is entered from, when the line does not say it: + /// `{ incomplete: [complete, on_hearing] }` sends a case back for + /// papers it was already past, and `{ changed_by_us: [reconsidered] }` + /// puts a good ending somewhere other than the end of the line. + /// Naming a stage here replaces the moves into it that the line + /// would have given, and only those - every other stage keeps its + /// own. A regulated case needs both: an authority may refuse only + /// once the papers are complete, while the applicant may withdraw + /// from anywhere, and the two cannot be one list. + #[serde(default)] + #[serde(deserialize_with = "one_or_many_by_key")] + pub reached_from: BTreeMap>, /// What the person must already have or be for this alternative to /// work: a membership, a reference number, the link from a mail, /// an account. Stated on the card before the form, because a @@ -381,8 +393,36 @@ impl Plan { if need.watched_by.iter().any(|g| !is_id(g)) { bail!(at("watched_by must list group identifiers, or `public`")); } - if need.watched_by.iter().any(|g| g == PUBLIC) && need.enters_as.is_some() { - bail!(at("a public view is for what the public sent; an internal need has its group's desk")); + // A public view is of a bucket, not of a need. A role's own + // need may be watched by the public when the public files + // into the same bucket: a permit register holds the owner's + // small application and the firm's large one, and is one + // page either way. A bucket only a role ever writes to has + // its group's desk and nothing to publish. + if need.watched_by.iter().any(|g| g == PUBLIC) + && need.enters_as.is_some() + && !self + .needs + .iter() + .any(|n| n.lands_in == need.lands_in && n.enters_as.is_none()) + { + bail!(at("a public view is for what the public sent; an internal need whose bucket the public never files into has its group's desk")); + } + for (target, froms) in &need.reached_from { + if !need.stages.contains(target) || target == &need.stages[0] { + bail!(at(&format!("reached_from names {target:?}, which is not one of its stages after the first"))); + } + if froms.is_empty() { + bail!(at(&format!("reached_from {target:?}: a stage reached from nowhere can never be entered"))); + } + for from in froms { + if !need.stages.contains(from) || need.done_when.contains(from) { + bail!(at(&format!("reached_from {target:?} names {from:?}, which is not one of its unfinished stages"))); + } + if from == target { + bail!(at(&format!("reached_from {target:?} names itself"))); + } + } } for state in &need.turned_down_from { if need.done_when.contains(state) || !need.stages.contains(state) { @@ -480,6 +520,7 @@ impl Plan { || other.mails != first.mails || other.stages_text != first.stages_text || other.turned_down_from != first.turned_down_from + || other.reached_from != first.reached_from { bail!("needs {:?} and {:?} both land in {bucket:?} and must agree on stages, done_when, skippable, events, attended_by, mails and who moves and watches it", first.id, other.id); } @@ -532,6 +573,14 @@ impl Plan { /// beyond a run of skippable ones, plus every finished state that is /// not a success (a case can be turned down at any point). Success is /// only reachable from the end of the line. +/// +/// That line is what most work looks like, and it is not what a +/// regulated case looks like. `reached_from` says where a named stage +/// is entered from instead: back to an earlier one when a case is sent +/// for the papers it was missing, or into a good ending partway along +/// when an authority changes its own mind rather than passing the case +/// on. A stage named there is entered from exactly those stages and +/// nowhere else; every stage not named keeps the line's own answer. pub fn machine(need: &PlanNeed) -> BTreeMap> { let line: Vec<&String> = need.stages.iter().filter(|s| !need.done_when.contains(s)).collect(); let ends_well: Vec<&String> = if need.success.is_empty() { need.done_when.iter().collect() } else { need.success.iter().collect() }; @@ -560,6 +609,22 @@ pub fn machine(need: &PlanNeed) -> BTreeMap> { } moves.insert((*stage).clone(), to); } + // A stage the plan places by hand is entered from exactly the + // stages it names: take it out of the line's answer everywhere + // first, so that saying where a refusal may come from also says + // where it may not. + for (target, froms) in &need.reached_from { + for tos in moves.values_mut() { + tos.retain(|to| to != target); + } + for from in froms { + if let Some(tos) = moves.get_mut(from) { + if !tos.contains(target) { + tos.push(target.clone()); + } + } + } + } moves } @@ -1740,11 +1805,25 @@ mod tests { lands_in: "b".into(), handled_by: "g".into(), stages: v(stages), done_when: v(done), success: v(success), skippable: v(skippable), moves_by: BTreeMap::new(), watched_by: vec![], - events: BTreeMap::new(), attended_by: None, mails: BTreeMap::new(), stages_text: BTreeMap::new(), turned_down_from: vec![], requires: String::new(), + events: BTreeMap::new(), attended_by: None, mails: BTreeMap::new(), stages_text: BTreeMap::new(), turned_down_from: vec![], reached_from: BTreeMap::new(), requires: String::new(), collects: vec![], max_fields: 3, } } + fn map(pairs: &[(&str, &[&str])]) -> BTreeMap> { + pairs.iter().map(|(k, vs)| (k.to_string(), vs.iter().map(|v| v.to_string()).collect())).collect() + } + + fn m_of(need: &PlanNeed, stage: &str) -> Vec { + machine(need).remove(stage).unwrap_or_default() + } + + fn parse(yaml: &str) -> anyhow::Result { + let plan: Plan = serde_yaml::from_str(yaml)?; + plan.validate()?; + Ok(plan) + } + #[test] fn a_stage_may_mail_the_submitter_or_an_address_and_the_words_fill_it() { let yaml = "business: B\ncontact: { name: I, email: i@b.example }\nmail: { from: \"B \", reply_to: i@b.example }\nneeds:\n - id: leak\n who: owners\n wants: a dry house\n lands_in: leaks\n handled_by: roofers\n stages: [open, fixed, dropped]\n done_when: [fixed, dropped]\n success: [fixed]\n moves_by: { dropped: [submitter, roofers] }\n mails: { open: submitter, fixed: submitter, dropped: board@b.example }\n max_fields: 2\n collects:\n - { name: name }\n - { name: email, type: email }\n"; @@ -1819,6 +1898,64 @@ mod tests { assert!(!m.contains_key("won")); } + // A building case is sent back for the drawing it was missing and + // walks the same stretch again. The line alone only goes forward, + // so the plan says where `incomplete` is entered from. + #[test] + fn a_case_can_be_sent_back_for_what_it_was_missing() { + let mut n = need( + &["open", "incomplete", "complete", "on_hearing", "approved", "refused"], + &["approved", "refused"], + &["approved"], + &["incomplete"], + ); + assert_eq!(m_of(&n, "on_hearing"), ["approved", "refused"]); + assert!(!m_of(&n, "on_hearing").contains(&"incomplete".to_string())); + n.reached_from = map(&[("incomplete", &["complete", "on_hearing"][..])]); + let m = machine(&n); + assert_eq!(m["on_hearing"], ["approved", "refused", "incomplete"]); + assert_eq!(m["complete"], ["on_hearing", "refused", "incomplete"]); + // And nowhere else: `open` no longer reaches it, because saying + // where a stage is entered from says where it is not. + assert_eq!(m["open"], ["complete", "refused"]); + } + + // The authority that changes its own mind ends the case at + // `changed_by_us`, which is a good ending in the middle of the + // line, not at the end of it. + #[test] + fn a_good_ending_can_sit_partway_along() { + let mut n = need( + &["open", "reconsidered", "before_the_board", "changed_by_us", "upheld", "overturned"], + &["changed_by_us", "upheld", "overturned"], + &["changed_by_us", "upheld"], + &[], + ); + // By the line alone, we change our own mind only once the board + // already has the case - which is backwards. + assert!(m_of(&n, "before_the_board").contains(&"changed_by_us".to_string())); + assert!(!m_of(&n, "reconsidered").contains(&"changed_by_us".to_string())); + n.reached_from = map(&[ + ("changed_by_us", &["reconsidered"][..]), + ("overturned", &["before_the_board"][..]), + ]); + let m = machine(&n); + assert_eq!(m["reconsidered"], ["before_the_board", "changed_by_us"]); + assert_eq!(m["before_the_board"], ["upheld", "overturned"]); + assert!(!m["open"].contains(&"overturned".to_string())); + } + + #[test] + fn a_stage_reached_from_nowhere_real_is_refused() { + let base = "business: B\ncontact: { name: I, email: i@b.example }\nneeds:\n - id: apply\n who: owners\n wants: permission\n lands_in: cases\n handled_by: office\n stages: [open, checked, approved, refused]\n done_when: [approved, refused]\n success: [approved]\n max_fields: 2\n collects:\n - { name: what }\n"; + let with = |line: &str| format!("{base} reached_from: {line}\n"); + assert!(parse(&with("{ approved: [checked] }")).is_ok()); + assert!(parse(&with("{ signed: [checked] }")).unwrap_err().to_string().contains("not one of its stages")); + assert!(parse(&with("{ approved: [approved] }")).unwrap_err().to_string().contains("not one of its unfinished stages")); + assert!(parse(&with("{ open: [checked] }")).unwrap_err().to_string().contains("after the first")); + assert!(parse(&with("{ approved: [] }")).unwrap_err().to_string().contains("never be entered")); + } + #[test] fn a_stated_prerequisite_comes_before_the_form() { let yaml = "business: B\ncontact: { name: I, email: i@b.example }\nneeds:\n - id: renew\n who: members\n wants: another year\n requires: You need your membership number from last year's receipt.\n lands_in: renewals\n handled_by: office\n stages: [open, done]\n done_when: [done]\n max_fields: 2\n collects:\n - { name: number }\n"; diff --git a/src/plan.rs b/src/plan.rs index 073a441..58d5bc0 100644 --- a/src/plan.rs +++ b/src/plan.rs @@ -78,6 +78,16 @@ needs: # the unfinished stages a case can still be turned down from; # omit for every one. An applicant is declined before they # start, not after - after, they depart + reached_from: { : [, ...] } + # where a stage is entered from, when the line does not say it. + # Two things need it and nothing else does: a case SENT BACK to + # a stage it was already past ("papers missing" again, after the + # hearing turned something up), and a GOOD ENDING partway along, + # where a case finishes well without walking to the end ("we + # changed our own decision", instead of passing it upwards). + # A stage named here is entered from exactly those stages and + # nowhere else, so it also says where a refusal may NOT come + # from. Omit unless the business described one of those two moves_by: { : [, ...] } # only where someone other than handled_by moves a case INTO a # stage: another group, or `submitter` (the person who sent the