Files
portal/runs/contractor-full-2026-09-21/README.md
T
Bendik Aagaard LynghaugandClaude Fable 5.1 baf36319b7 Overlapping roles on one aggregate, relay routes, and a dry run
plan.yaml: `moves_by` says who presses the button into a stage when it
is not `handled_by` - other groups, several groups, or `submitter`,
the person who sent the form, through their own link (the form must
then collect a required email). `watched_by` puts a bucket on a
group's desk with no buttons. Each group's desk carries its own buttons
only; a submitter's moves become a followup page of self_transitions;
needs.yaml gains `also_moved_by` for portal's verifier.

simulate: a route is now a relay across every role that holds a legal
button, the submitter included, and each step is judged as the role
that presses it. `--dry` asks no model anything and walks every simple
route of every aggregate, for needs_replay to put through the real
engine.

plans/contractor-full.yaml: 13 needs, 6 roles, 10 aggregates. Verifier
green by construction; 40 routes, 78 transitions accepted by the real
engine, none refused. What it exposed is in its run README.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L4jrCgLiKKHAEFuZUJjckH
2026-09-21 21:46:12 +02:00

2.3 KiB

The whole operation: 13 needs, 6 roles, 10 aggregates, overlapping

Plan: plans/contractor-full.yaml. Built with no model, walked dry (every route of every aggregate), and replayed through portal's real aggregate engine on a throwaway NATS.

Verifier 13 of 13 needs met, 28 pages, by construction
Routes walked 40, of which 6 are relays between roles
Real engine 40 aggregates created, 78 transitions accepted, 0 refused, 118 events

Who holds buttons on what, as built:

  • enquiries: project managers (6), site managers (mark surveyed; otherwise watch)
  • claims: site managers inspect and fix, project managers accept or reject
  • change_orders: project managers price, the client approves or declines through their own link, site managers complete
  • material_orders: site managers order, the crew confirms delivery
  • site_issues: site managers or the safety officer take in hand, only the safety officer closes; project managers watch
  • job_requests: project managers award; subcontractors watch, which is how they see what there is to bid on

What this plan exposed, none of it fixed yet:

  1. The project managers' desk is one page with 9 aggregates and 32 buttons. The builder puts every aggregate a role touches on one desk page. Past a handful it has to tier: a hub that lists the aggregates with what is waiting in each, and a page per aggregate.
  2. The front door offers 6 alternatives, one over the page-load limit. It wants a first question ("a building of yours", "work with us", "a site of ours next door") and a second page under each.
  3. Aggregates do not know about each other. A bid names its job in a free-text field; a change request names its job by address. Nothing says "a bid belongs to a job request" or "a change order exists only while an enquiry is won". That is the tiering between state machines still to be designed: a need that arises when a record elsewhere reaches a state, and carries its id.
  4. A shared button is walked by one role only. Where two roles both hold open -> surveyed, the dry run presses it as the first of them.
  5. Anyone in clients opens the change-request form, and portal has no per-record ownership beyond the submitter's link, so a client group sees nothing of its own cases afterwards.