Files
portal/runs/permits-2026-09-25/fixed/needs.yaml
T
Bendik Aagaard LynghaugandClaude Opus 5 d2aae383b2 A case can be sent back, and can end well partway along
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>
2026-09-25 20:17:06 +02:00

431 lines
9.5 KiB
YAML

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: []