A municipal building authority is the first sector that the line a
case walks could not describe. An application is returned for the
drawing it was missing and walks the same stretch again; an appeal
ends the moment the authority changes its own decision, without ever
reaching the board; an applicant may withdraw from anywhere, while a
refusal may only come once the papers are in.
`reached_from: { <stage>: [<stage>, ...] }` says where a stage is
entered from when the line does not. 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 - which `turned_down_from`
could not, being one list for every bad ending at once.
Found by replaying fifteen real building cases through portal's own
engine against a throwaway JetStream: it refused three legal paths and
accepted two illegal ones. Portal needed no change - hand-writing the
correct graph into aggregates.yaml, cycle and all, was accepted and
enforced exactly. The rebuilt site now produces that same graph from
the plan, and the access policy follows it.
Also: a public view is of a bucket, not of a need. A permit register
holds the owner's small application and the approved firm's large one
and is one page either way; the rule refused to publish a bucket the
moment any role filed into it. A bucket only a role ever writes to is
still refused.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
16 lines
4.2 KiB
JSON
16 lines
4.2 KiB
JSON
{"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"]}
|