Every prompt and reply is now kept under <out>/llm/. An empty reply is a retry, not a fatal error; a spec that never parses stops the run before the structure phase; --visitor-llm lets a different model play the visitor. The file-block parser finds markers anywhere in a line, accepts a short END and lets a new FILE close an open one, after a reply glued two files together with `<<<END>></think>`. The reference gains a language section: copy in the intake's language, identifiers in ASCII. runs/rehab-entreprenor-no-2026-09-21: nemotron-3.5-lightning:30b-a3b did not produce a loadable site. Written up with the reason and the way forward: structure from needs.yaml deterministically, words from the model. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L4jrCgLiKKHAEFuZUJjckH
13 KiB
<<>> title: Åsrud Bygg og Rehabilitering AS lang: no <<>>
<<>> needs:
- id: leads who: styreledere i borettslag og sameier, private huseiere wants: at noen skal se på et problem med bygget enters: / lands_in: leads handled_by: prosjektledere done_when: [won, lost] max_steps: 1 max_fields: 4 success: [won] stages: [open, quoted, won, lost]
- id: subcontractors who: underentreprenører (tømrere, murere, lærlinger) wants: å bli godkjent som fast leverandør enters: / lands_in: subcontractors handled_by: prosjektledere done_when: [approved, rejected] max_steps: 1 max_fields: 3 success: [approved] stages: [open, approved, rejected]
- id: job_applications who: personer som søker jobb wants: å bli ansatt som tømrer, murer eller lærling enters: / lands_in: job_applications handled_by: prosjektledere done_when: [hired, rejected] max_steps: 2 max_fields: 6 success: [hired] stages: [open, interviewed, hired, rejected]
- id: incident_reports who: HMS-ansvarlig, mandskap på byggeplass wants: å rapportere avvik og uønskede hendelser enters: / lands_in: incident_reports handled_by: HMS-ansvarlig done_when: [closed] max_steps: 1 max_fields: 3 success: [closed] stages: [open, closed]
- id: internal_referral who: prosjektledere wants: anbefalinger av kvalifisert mandskap enters: / lands_in: internal_referral handled_by: prosjektledere done_when: [referred] max_steps: 1 max_fields: 2 success: [referred] stages: [open, referred] <<>>
<<>> aggregates:
- bucket: leads initial: open states: open: { event: received } quoted: { event: quoted } won: { event: won } lost: { event: lost } transitions: open: [quoted, lost] quoted: [won, lost]
- bucket: subcontractors initial: open states: open: { event: received } approved: { event: approved } rejected: { event: rejected } transitions: open: [approved, rejected] approved: [] rejected: []
- bucket: job_applications initial: open states: open: { event: received } interviewed: { event: interviewed } hired: { event: hired } rejected: { event: rejected } transitions: open: [interviewed] interviewed: [hired, rejected] hired: [] rejected: []
- bucket: incident_reports initial: open states: open: { event: reported } closed: { event: closed } transitions: open: [closed] closed: []
- bucket: internal_referral initial: open states: open: { event: referred } referred: { event: referred } transitions: open: [referred] referred: [] <<
<<<FILE questions/index.yaml>>> name: Hva hjelper du på? description: > Vi hjelper med tilstandsrapporter, prosjektering, byggesøknad og jobb. responsible: { name: Marte Åsrud, email: marte@asrudbygg.example } alternatives:
- name: Melding om problem med bygget description: > action: /leads consequence: [Send] record_as: leads
- name: Melding om underentreprenør description: > action: /subcontractors consequence: [Send] record_as: subcontractors
- name: Søk jobb description: > action: /job_applications consequence: [Send] record_as: job_applications
- name: Melding om avvik på byggeplass description: > action: /incident_reports consequence: [Send] record_as: incident_reports
- name: Anbefaling av kompetanse description: > action: /internal_referral consequence: [Send] record_as: internal_referral <<
<<<FILE questions/leads.yaml>>> name: Hva problemet gjelder description: > Fortell kort hva som trenger å gjøres med bygget ditt. responsible: { name: Marte Åsrud, email: marte@asrudbygg.example } alternatives:
- name: Send tilbud
description: >
action: /leads/quoted
consequence: [Send]
record_as: leads
features:
- name: E-post
description: >
requirements:
- { name: email, label: E-post, type: email }
- { name: problem, label: Hva er problemet, type: textarea }
- { name: urgency, label: Hvor snart, type: select, options: [I denne uken, I denne måneden, Ikke akutt] }
- { name: address, label: Adresse, optional: true }
- name: E-post
description: >
requirements:
- name: Avslå description: > action: /leads/lost consequence: [Send] record_as: leads <<
<<<FILE questions/leads/quoted.yaml>>> name: Tilbud sendt description: > Vi sender et tilbud på arbeidet. responsible: { name: Marte Åsrud, email: marte@asrudbygg.example } alternatives:
- name: Aksepter tilbudet description: > action: /leads/won consequence: [Godkjenn] record_as: leads
- name: Trekke tilbudet description: > action: /leads/lost consequence: [Avslå] record_as: leads <<
<<<FILE questions/subcontractors.yaml>>> name: Melding om underentreprenør description: > Fortell kort hvem du er og hva du kan. responsible: { name: Marte Åsrud, email: marte@asrudbygg.example } alternatives:
- name: Godkjenn
description: >
action: /subcontractors/approved
consequence: [Godkjenn]
record_as: subcontractors
features:
- name: Organisasjonsnummer
description: >
requirements:
- { name: org_number, label: Organisasjonsnummer, type: text }
- { name: hms_kort, label: HMS-kort, type: select, options: [Har, Ikke har] }
- { name: insurance, label: Forsikring, type: select, options: [OK, Mangler] }
- { name: availability, label: Tilgjengelighet, type: select, options: [Normalt, Begrenset] }
- name: Organisasjonsnummer
description: >
requirements:
- name: Avslå description: > action: /subcontractors/rejected consequence: [Avslå] record_as: subcontractors <<
<<<FILE questions/subcontractors/approved.yaml>>> name: Godkjent som leverandør description: > Underentreprenøren er godkjent. responsible: { name: Marte Åsrud, email: marte@asrudbygg.example } alternatives:
- name: Gå tilbake til hovedmeny description: > action: / consequence: [Tilbake] record_as: subcontractors <<
<<<FILE questions/subcontractors/rejected.yaml>>> name: Ikke kvalifisert description: > Underentreprenøren blir ikke godkjent nå. responsible: { name: Marte Åsrud, email: marte@asrudbygg.example } alternatives:
- name: Gå tilbake til hovedmeny description: > action: / consequence: [Tilbake] record_as: subcontractors <<
<<<FILE questions/job_applications.yaml>>> name: Stillingsansøkning description: > Fortell kort hvem du er og hva du kan. responsible: { name: Marte Åsrud, email: marte@asrudbygg.example } alternatives:
- name: Send påmelding
description: >
action: /job_applications/interviewed
consequence: [Send]
record_as: job_applications
features:
- name: Navn
description: >
requirements:
- { name: name, label: Navn, type: text }
- { name: phone, label: Telefon, type: tel }
- { name: email, label: E-post, type: email }
- { name: experience, label: Erfaring, type: textarea }
- name: Navn
description: >
requirements:
- name: Avslå påmelding description: > action: /job_applications/rejected consequence: [Avslå] record_as: job_applications <<
<<<FILE questions/job_applications/interviewed.yaml>>> name: Intervju description: > Vi kaller deg til intervju. responsible: { name: Marte Åsrud, email: marte@asrudbygg.example } alternatives:
- name: Ansett description: > action: /job_applications/hired consequence: [Ansett] record_as: job_applications
- name: Takk nei description: > action: /job_applications/rejected consequence: [Avslå] record_as: job_applications <<
<<<FILE questions/job_applications/hired.yaml>>> name: Ansett description: > Du blir ansatt som tømrer, murer eller lærling. responsible: { name: Marte Åsrud, email: marte@asrudbygg.example } alternatives:
- name: Gå tilbake til hovedmeny description: > action: / consequence: [Tilbake] record_as: job_applications <<
<<<FILE questions/job_applications/rejected.yaml>>> name: Takk nei description: > Vi takker nei til din påmelding. responsible: { name: Marte Åsrud, email: marte@asrudbygg.example } alternatives:
- name: Gå tilbake til hovedmeny description: > action: / consequence: [Tilbake] record_as: job_applications <<
<<<FILE questions/incident_reports.yaml>>> name: Rapporter avvik description: > Fortell kort hva som har skjedd. responsible: { name: Marte Åsrud, email: marte@asrudbygg.example } alternatives:
- name: Lukk saken
description: >
action: /incident_reports/closed
consequence: [Lukk]
record_as: incident_reports
features:
- name: beskrivelse
description: >
requirements:
- { name: description, label: Hva skjedde, type: textarea }
- { name: avvik_type, label: Typen avvik, type: select, options: [Løse rekkverk, Nestenulykke, Feil materialer] }
- { name: rapportert_av, label: Hvem rapporterte, type: text }
- name: beskrivelse
description: >
requirements:
- name: Avslå å rapportere description: > action: /incident_reports/closed consequence: [Avslå] record_as: incident_reports <<
<<<FILE questions/incident_reports/closed.yaml>>> name: Saken er lukket description: > Avviket er løst og saken lukkes. responsible: { name: Marte Åsrud, email: marte@asrudbygg.example } alternatives:
- name: Gå tilbake til hovedmeny description: > action: / consequence: [Tilbake] record_as: incident_reports <<
<<<FILE questions/internal_referral.yaml>>> name: Anbefaling av kompetanse description: > Fortell kort hvem du anbefaler og hvorfor. responsible: { name: Marte Åsrud, email: marte@asrudbygg.example } alternatives:
- name: Send anbefaling
description: >
action: /internal_referral/referred
consequence: [Send]
record_as: internal_referral
features:
- name: Navn
description: >
requirements:
- { name: name, label: Navn, type: text }
- { name: role, label: Rolle, type: text }
- { name: contact, label: Kontakt, type: email }
- name: Navn
description: >
requirements:
- name: Avslå anbefaling description: > action: /internal_referral/referred consequence: [Avslå] record_as: internal_referral <<
<<<FILE questions/internal_referral/referred.yaml>>> name: Anbefaling sendt description: > Anbefalingen er sendt videre. responsible: { name: Marte Åsrud, email: marte@asrudbygg.example } alternatives:
- name: Gå tilbake til hovedmeny description: > action: / consequence: [Tilbake] record_as: internal_referral <<
<<<FILE questions/desk/_section.yaml>>> qualifies: prosjektledere <<
<<<FILE questions/desk/index.yaml>>> name: Hva kom inn? description: > Henvendelser og saker som trenger handling. responsible: { name: Marte Åsrud, email: marte@asrudbygg.example } alternatives:
- name: Leads
description: >
action: /desk
consequence: [Confirm]
record_as: leads
features:
- name: "" description: "" resource: source: { kind: kv, bucket: leads } requires_group: prosjektledere transitions: - { to: quoted, label: Quote sent } - { to: lost, label: Not for us } - { from: quoted, to: won, label: Won } - { from: quoted, to: lost, label: Lost }
- name: Subcontractors
description: >
action: /desk
consequence: [Confirm]
record_as: subcontractors
features:
- name: "" description: "" resource: source: { kind: kv, bucket: subcontractors } requires_group: prosjektledere
- name: Job applications
description: >
action: /desk
consequence: [Confirm]
record_as: job_applications
features:
- name: "" description: "" resource: source: { kind: kv, bucket: job_applications } requires_group: prosjektledere
- name: Incident reports
description: >
action: /desk
consequence: [Confirm]
record_as: incident_reports
features:
- name: "" description: "" resource: source: { kind: kv, bucket: incident_reports } requires_group: HMS-ansvarlig
- name: Internal referrals
description: >
action: /desk
consequence: [Confirm]
record_as: internal_referral
features:
- name: "" description: "" resource: source: { kind: kv, bucket: internal_referral } requires_group: prosjektledere <<