Entity screen specification

Table of Contents

1. Summary

The Record screen standard defines the screen of one kind of record: a currency, a calendar, a role. Some things a person works with are not one record. A person is an account, a contact record, the roles they hold, their sign-ins, the parties they work in and who they report to, and each of those has its own table, its own permission and its own history. This page defines the look and feel of the screen for such an entity. The Staff screens are the reference.

The rules in short:

  • One page per subject, with one tab per aspect. A tab the reader may not read is not drawn.
  • Every list pages on the server, and the pager on the screen is the request. No screen reads an entity whole.
  • Every reference to another record is a link to that record's page: a person, a currency, a country, a calendar, a party. One system-wide mechanism draws it, and a screen never builds the address itself.
  • Every mention of a person is a link to the person, with their photo where the place has room for one. A username is always drawn with the photo, on every tab and in every panel. The one exception is the accounts dialog itself. An email is a mailto: link and a web address an http link.
  • Every change is made in a dialog opened by an Edit button on the card it changes. The reason is asked in the dialog and nowhere else.
  • History is a chart of events over time above a rail of one-line headers with the detail on demand. The author's photo stands at the left of each entry, and the note stands on its own line below the header.
  • A combo box offers only values that exist, and a screen that shows one value at a time has no "all" choice.
  • The main screen of an entity contains the workflows that act on it, in a Workflows menu in its header. A workflow is never a card on an area page when the entity has a screen to hold it.
  • A screen learns that its data changed, turns Refresh gold, and waits for the reader. It never reloads by itself, and it never loses an edit.

2. Detail

2.1. Where this page applies

An entity screen is a screen whose subject is one thing made of several kinds of record, which a person reads and changes together. The Staff list and the page of one person are the reference. The tenant, the party and the role are close to it. Hierarchy, Requests and Where I work are screens about relationships between entities and follow the rules on people, history and paging here.

A kind of record with one table and no aspects is still a record screen. Use the Record screen standard for it. This page adds to that standard and never replaces it. Where the two disagree on the same thing, the record standard rules for a screen of one record kind, and this page rules for an entity.

2.2. User journeys and screens

A user journey says what a person is trying to do. A screen is a part of the interface. The two are not the same shape, and a screen is never a journey copied step by step.

  • ES-JOURNEY-01 A journey is a design document. It names the goal, the actor, the reads and writes it needs, and what is missing. It stays as it is.
  • ES-JOURNEY-02 The screens that serve a journey follow the UX standards: the list, the page of one subject, the cards, the dialogs and the history. One journey is usually served by several standard screens, and one screen serves several journeys.
  • ES-JOURNEY-03 A wizard is the exception. Use a guided sequence of steps only when it makes the task easier or quicker for the person, for example the first run of an installation or the setup of a tenant. Editing a record, or a record made of several kinds of record, is not such a task. It is done on the page of the subject, with an Edit button on each card.
  • ES-JOURNEY-04 A change that needs a second person is not a different screen. The person saves in the usual dialog, and the save proposes the change. See Proposals and four-eyes.

2.3. Words

Word Meaning
Entity A subject made of several kinds of record, such as a person
Aspect One kind of record of an entity, or one view of it: details, contact, roles, sign-ins, history
Subject The one entity a page is about
Card A bordered panel holding one aspect's fields, with its title and its Edit button
Directory The people the reader may name, read from the widest read they hold
Self read A read of the signed-in person's own record, which needs no permission
Gap A part of a stream that the server cannot answer, stated on the screen
Window One page of rows, asked for by offset and limit
Workflow A guided sequence of steps with several writes and a step rail, such as onboarding a party. It is not a CRUD command (Add, Edit, Delete)

2.4. The shape of an entity screen

An entity has three screens, and each has one job.

Screen Job Address
The list Find a subject, and see enough of each to choose /staff
The page Read and change one subject, one aspect per tab /people/:username
The relationship views Show how subjects relate: a tree, a chart, a requests queue /hierarchy, /requests

The list opens the page. The page links back to the list through its breadcrumb, and to other subjects through people links. A relationship view opens the page of any subject it draws.

A reader sees a screen only if the menu offers it, and the menu offers it by the narrowest read the screen needs. Menu structure names the areas and the screen that belongs to each. A member does not hold the read of accounts, so Staff is a different list for them, built from the organisation read. See Who sees what.

2.5. The list

Home › Organisation › Staff
Staff                                                     [↻ Refresh]
The people of the parties you work in, and everyone who reports to you.
[ 🔍 Search by name, username or job title ]
──────────────────────────────────────────────────────────────────────
 Person              Username        Kind     Job title      Parties
──────────────────────────────────────────────────────────────────────
 (photo) Ada Lovelace  ada.lovelace  Person   Head of Desk   [Acme UK]
 …
──────────────────────────────────────────────────────────────────────
1–15 of 58      [« First] [‹ Previous] [Next ›] [Last »]   Page size [15 ▾]
  • ES-LIST-01 The first column is the person: their photo, then their name. A name opens the page. The username, the kind, the job title and the parties follow.
  • ES-LIST-02 The parties are tags with the party's name, not its code. A person in several parties shows each.
  • ES-LIST-03 The search, the sort, the filter and the page all go to the server. The list never reads every row to filter them itself.
  • ES-LIST-04 The header, the table, the states and the pager are those of the record standard's list. The titles are in sentence case.
  • ES-LIST-05 A list for a member names what it holds in its lead sentence, because it is not the whole tenant.

2.6. The page

Home › Organisation › Staff › Adrian Vance
(photo)  Adrian Vance
         1f3c…9a2e
[ Details ] [ Contact ] [ Roles ] [ Sign-ins ] [ History ]
┌─ Photo and identity ───────────────────────────────── v7  [✎ Edit] ─┐
│ Full name        Job title                                          │
│ Adrian Vance     Group Chief Executive Officer                      │
│ Username         Sign-in address        Account type                │
│ adrian.vance     adrian.vance@…         user                        │
│ ─ Reporting line ───────────────────────────────────────────────── │
│ (photo) Grace Hopper   Chief of Staff                  [↗ Propose]  │
└─────────────────────────────────────────────────────────────────────┘

2.6.1. Header

  • ES-PAGE-01 The breadcrumb is Home, the area, the list, then the subject. The areas are in Menu structure.
  • ES-PAGE-02 The photo stands large beside the title. The title is the person's name.
  • ES-PAGE-03 Under the title, in small subdued type, is the subject's identifier. Nothing else. The version stands on each card, beside its title, because each card is a different record with its own version.
  • ES-PAGE-04 A trade is the one exception. The line under its title also carries the trade's state, its internal version and its external version, because the two-version rule of Trade Versioning is what a person reads a trade for. The cards still carry their own versions.
  • ES-PAGE-05 The header carries no Edit button. Edit belongs to the card it changes, because each card is its own record. This is the one rule of the Record screen standard's Header, Edit stands on the thing it changes, applied to an entity (decided 2026-10-25).

2.6.2. Tabs

Tabs are held in the address (?tab=roles), so a link reopens the page on a tab. They run in this order, and a tab appears only when the reader may read it.

Tab Holds Shown when
Details The identity card and the reporting line Always
Contact The contact record The reader may read contact records, or it is their own
Roles The roles held, then what they allow The reader may read roles
Sign-ins The sign-in state and the sessions The reader may read sessions
History The timeline The reader may read the history of the subject. The tab is always drawn, and the timeline states what it cannot answer

A tab that would answer with a refusal is not drawn. A refusal that arrives anyway is stated on the tab in words, with the reason, and the page does not show a banner for it: the read that can be refused is made quietly, and the tab speaks for it.

2.6.3. Cards

Each aspect that a person can change is one card.

  • ES-PAGE-06 The card's title is on the left. The version of the record it shows is small and subdued beside it. The Edit button is on the right.
  • ES-PAGE-07 The fields are read as text, not as inputs. A label stands above each value in sentence case, with no colon. A value with nothing in it is a muted dash.
  • ES-PAGE-08 A field that is fixed once the record exists, such as the username, says why in a line of small text under it: "Set when the account was made, and never changed here."
  • ES-PAGE-09 A field that another person owns says who. The sign-in address says "An administrator owns it."
  • ES-PAGE-10 A card the reader may not change shows the access mark, Read only, as the UX Language sets it.

2.7. Changing a record

2.7.1. The Edit pattern

  • ES-EDIT-01 Edit is one button with an icon and the word Edit, on the card it changes. It is drawn only for a person who may change that card.
  • ES-EDIT-02 Edit opens a dialog with the current values. The dialog is titled Edit followed by the card's title, the entity's shape of the Record screen standard's Amend rule. It asks for the change reason and the commentary. The card itself asks for neither, and shows no reason field beside its values.
  • ES-EDIT-03 Save is enabled once the form is complete, and a save with no field change is allowed: it writes a version that carries only its reason, which the history model keeps (decided 2026-10-25; the rule is the Record screen standard's Amend). The reasons offered follow the change: when a field changed, "No change in substance" is not offered, and when nothing changed only that reason is.
  • ES-EDIT-04 The write claims the version that was read. A record that has changed since is refused with a conflict, and the dialog says so and offers to reload.
  • ES-EDIT-05 Closing the dialog with changes asks "You have unsaved changes. Close anyway?"
  • ES-EDIT-06 An optional field has a Clear control beside it, which writes the empty value. A Clear is not a Save of a blank by accident.

2.7.2. Small controls

  • ES-EDIT-07 A change that is not a form, such as the reporting line, has a small icon button on the line it changes. It is drawn only when the reader may use it.
  • ES-EDIT-08 The photo is its own control. Clicking the photo opens the chooser to replace it. There is no separate "Replace photo" button.
  • ES-EDIT-09 A control that proposes and does not write, such as a change that another person must approve, says Propose and not Save. See Proposals and four-eyes.

2.7.3. Changes the reader may not make

The control is not drawn. A disabled button asks a question that a missing one does not. The server still decides every write; the screen hides only what the server would refuse.

2.8. References are links

A value that names another record is a reference. It is a foreign key on the record that holds it: the currency of a trade, the country of an address, the calendar of a convention, the party of a book, the account of a sign-in. The rule is the same for every kind of record, and it is the rule for a person below.

  • ES-REF-01 A reference is a link to the page of the record it names. The text of the link is the record's name, or its code where the record has no name, and the record's flag or photo stands beside it where the record has one.
  • ES-REF-02 The link is the same on every screen, in every table, card, panel, history entry and chart. It is not a choice of the screen.
  • ES-REF-03 The address comes from one place. A screen gives the kind of record and its key, and the shared mechanism returns the address and says whether the reader may open it. A screen never writes /refdata/currencies/... or any other record address in its own code.
  • ES-REF-04 A reference is plain text, never a link that goes nowhere, in four cases: the reader may not read the record, the kind of record has no page of its own, the record does not exist, and the reference is to the record whose page is open.
  • ES-REF-05 A kind of record that is referenced but has no page yet is a gap in the product. The reference is drawn as text with its flag, and the gap is filed as a story. It is not hidden by writing the address anyway.
  • ES-REF-06 A new foreign key on a record is drawn as a reference from the day it is added. A review of a screen checks every value that is a key.
Kind of record Address Beside the text
Person /people/:username The photo
Currency /refdata/currencies/:code The flag
Currency pair /refdata/currency-pairs/:code The two flags
Calendar /refdata/calendars/:code The flag of its country
Desk group /refdata/desk-groups/:code Nothing
Classification value /refdata/classifications/:list/:code Nothing
Country No page yet The flag

Today the shared mechanism does not exist. Each screen uses the address function of the kind it knows (personPath, currencyPath, calendarPath, pairPath, deskGroupPath, classificationsPath), and some references, such as a country code, are text. The story "Link every reference to its record" builds the mechanism and moves the screens onto it.

2.9. Workflows on the entity screen

The main screen of an entity contains the workflows that act on it. A person who looks at the parties finds how to onboard one there, and does not have to know which area page holds the workflow.

  • ES-WORKFLOW-01 The workflows are in one Workflows menu in the header of the list, beside Refresh. An entity with a page of its own carries the workflows that act on one subject in the same menu on that page.
  • ES-WORKFLOW-02 Each line of the menu has the workflow's name, which is a verb and its object, and one line about it. Choosing a line opens the workflow.
  • ES-WORKFLOW-03 A line is drawn only for a person who may start that workflow. If there is none, the menu is not drawn.
  • ES-WORKFLOW-04 A workflow is not a CRUD command. Add, Edit and Delete are buttons on the list or on a card. A workflow has several steps, so it has its own address and its own trail: Home, the area, the workflow.
  • ES-WORKFLOW-05 A workflow is listed once. It is listed on the screen of the entity it acts on. It has a card on its area page, in the workflow hue and with the tag Workflow, only when no screen of an entity can hold it. See Menu structure.
  • ES-WORKFLOW-06 The component is WorkflowMenu in shell/WorkflowMenu.tsx. It reads the workflows from the card registry (shell/cards.ts), where each workflow names the screen it acts on.

2.10. People are links

ES-PEOPLE-05 A person is named in many places: a manager, a holder of a role, the author of a history entry, the person who asked for something, the person who answered. The rule is the same in all of them.

What is on the screen How it is drawn
A person the reader can name Their full name, then their username in brackets: "Ada Lovelace (ada.lovelace)"
A person the reader may open The name above is a link to their page
A person the reader can name but not open The same text, not a link
A name that is a service Text, not a link: a service has no page
An identifier no read can resolve "Someone outside your view". The identifier is never shown
An email address A mailto: link
A web address An http or https link that opens in a new tab with rel"noopener noreferrer"=
A value that is neither Plain text. It never becomes a link that goes nowhere
  • ES-PEOPLE-01 PersonRef draws a person from a username or an identifier. It reads the directory once, and the directory is the widest read the reader holds. A reader of accounts names anybody in the tenant. A reader of the organisation names the people in their parties and under them. Anybody else names nobody.
  • ES-PEOPLE-02 actorPathFor decides whether a history author is linked.
  • ES-PEOPLE-03 A sign-in address is not a mail address and is not a mailto: link. Only the contact record's email is.
  • ES-PEOPLE-04 The email on the contact card says which address it is, and says that it is not the sign-in address.

2.11. Photos, flags and images

  • ES-PHOTO-01 A person is drawn with a photo wherever there is room for one: the list, the page header, a manager line, a card in a chart, a person in a picker and the history rail. Where a person has no photo, their initials stand in the same circle, so a list does not jump.
  • ES-PHOTO-02 A username is never drawn without the photo. This holds on every screen and on every tab of a screen, including the audit screens, where a username names who signed in, who failed to sign in or who ended a session. The photo stands at the left of the name, small in rows.
  • ES-PHOTO-03 The one exception is the accounts dialog itself, where the account is the subject of the dialog and its photo is already its own control.
  • ES-PHOTO-04 A screen that reads accounts by identifier reads the image identifier with the username, so that it can draw the photo. A reading that carries only the username does not leave the photo out. The screen reads the account list once and joins it.
  • ES-PHOTO-05 A photo is fetched by its image identifier, which the read already carries. A screen never asks for a person's picture once per row by username. The image is cached by its identifier for a year.
  • ES-PHOTO-06 The sizes are small (20 pixels) in rows, pickers and the rail, medium in cards, and large (56 pixels) in a page header.
  • ES-PHOTO-07 A country, a currency, a calendar or a business centre is drawn with its flag wherever its code appears. A country code on a contact card is the flag, then the code. Flags come from the one map in the record standard, and a screen never works out a flag itself.
  • ES-PHOTO-08 The photo of a person who wrote a history entry stands at the left of the entry, beside its header and changes. See History and the timeline.

2.12. Paging: the pager is the request

This is the rule that matters most, and the Staff work learned it the hard way.

The paging on the screen must match the paging of the data requests.

  • ES-PAGING-01 Every list of rows asks the server for one page: offset, limit, and the server's total. The pager, the page size and the "Showing 1–15 of 40" sentence are the request's own numbers. A screen that reads everything and slices it in the browser has a pager that is not a pager.
  • ES-PAGING-02 The search, the filter, the area and the sort are fields of the same request. The server applies them. A new search or filter returns to the first page.
  • ES-PAGING-03 A search is sent when the typing pauses, not on every key.
  • ES-PAGING-04 The default page is 15 rows, and the sizes are those of the record standard. No screen sets its own.
  • ES-PAGING-05 An entity is never read whole. That includes the lists a screen needs only to draw something else: the permissions of a role, the people who hold a role, the roles a person holds, the people a name is resolved against. Each of them is a page, or a lookup of the few rows the screen draws. The one exception is the classification list of the Record screen standard's Exceptions, which is short, reordered as a whole and bounded by the Load all rule of 1000 rows (decided 2026-10-25).
  • ES-PAGING-06 A count that a screen needs, such as how many people hold a role, is part of the answer to the page, not a second read of everything.
  • ES-PAGING-07 A thing that is not a list but looks like one to the reader, such as the catalogue of permissions, is paged by the unit the reader sees. A row on the screen is a resource with its actions, so a page is a whole number of resources and never half of one.

2.12.1. Combo boxes and filters

A combo box that filters a paged list obeys the same rule.

  • ES-PAGING-08 It offers only the values that exist in the data, and the server says which. An area no role grants something in is not offered.
  • ES-PAGING-09 A screen that shows one value at a time, such as one area of the permissions, has no "all" choice. One value is always chosen. When the reader has not chosen, the first value the server lists is chosen, and the server says which.
  • ES-PAGING-10 A list that narrows rows, such as the roles list, may start with "All areas", because choosing none shows every row. The first choice there means no filter, and it is not a page of everything.
  • ES-PAGING-11 A filter that matches nothing says so and offers to clear it.

2.12.2. Editing across pages

A change a person makes on one page must survive a move to another. The screen keeps the changes as a set of differences from what the server holds, keyed by the thing changed, and lays them over each page. A change that puts a value back as the server holds it removes the difference. Save sends only the differences, and the server applies them to what it holds. The screen never needs the whole set to save.

2.13. History and the timeline

An entity's history is one stream. It is drawn as a chart of events over time, and below it a rail of entries, newest first.

▂ ▅ ▁   ▇ ▃          ■ Created  ■ Changed  ■ Granted  ■ Signed in
10 Oct ─────────── 12 Oct

Saturday, 10 October 2026
03:51:36 ●  (photo) [Raised] account a452db76 v1  system.external_data_import
✓           ores_brave_hopper_iam_service  Published from organisation dataset
            Attached staff photo during provisioning
            ▸ Details
03:40:12 ●  (photo) [Changed] account a452db76 v2  Job Title   Rectification
            Marco Craveiro
            Corrected the title
            ▸ Details

2.13.1. The event chart

  • ES-HIST-01 The chart is a histogram of the entries: a bar for each hour, or for each day once the history spans more than two days. Each bar is split by the kind of entry, and each kind has one colour that the legend repeats.
  • ES-HIST-02 Every bar has the same fixed width. A bar never stretches to fill the row, and a long history scrolls sideways.
  • ES-HIST-03 An hour or a day with no entries is empty space. The chart draws every bucket from the first entry to the last, so a gap in time reads as a gap.
  • ES-HIST-04 A bar shows its time and its count on hover, and each segment its kind and its count. The first and the last time stand under the bars. The legend names the kinds that appear, each with its count.
  • ES-HIST-05 A click on a bar scrolls to the entry nearest that hour or day, and marks it for a moment. A click on an empty bar goes to the closest entry in time.
  • ES-HIST-06 The chart reads the entries the list holds. It makes no read of its own.

2.13.2. One line per entry

  • ES-HIST-07 Each entry is a header on one line: the kind, the record and its version, the reason code, the author, what they did, and the time. The time and the current-version emblem stand in the left gutter.
  • ES-HIST-08 The note, such as "Attached staff photo during provisioning", is never on the header line. It stands on its own line below the header.
  • ES-HIST-09 The detail is collapsed. A field that changed is drawn as the difference, the old and the new, and a first version as the whole record. A reader opens the detail on demand. The first screen of a long history is a list of headers a person can scan.
  • ES-HIST-10 An entry that changed no field says "No changes". It has no detail to open.
  • ES-HIST-11 The newest version of a record carries a small emblem next to its time, with the words "Current version" as its tooltip. There is no sentence for it, and no Revert button on it, because there is nothing to revert to.
  • ES-HIST-12 An entry that cannot be reverted, such as a sign-in, simply offers no control. The rail does not explain what is missing: no "this entry records something that happened, so there is nothing to revert", and no "putting a field back is not offered here". A sentence that says what is not there adds nothing.

2.13.3. System activity

  • ES-HIST-13 Every history draws one toggle, "Hide system activity". When it is on, the toggle reads "Show system activity". It is drawn even when no service account wrote an entry.
  • ES-HIST-14 The toggle starts off. A history shows every entry until the reader hides some.
  • ES-HIST-15 The toggle hides an entry only when its author is a service account. The tenant administrator and the super administrator are people, so their entries stay.
  • ES-HIST-16 The toggle also hides the entries in the chart, the legend and the day dividers. The chart counts what the rail shows.
  • ES-HIST-17 Only a reader who may read accounts can tell a service from a person. For any other reader the toggle is disabled, and its tooltip says why. The screen does not guess, because a wrong guess hides people.
  • ES-HIST-18 The shared Timeline draws the toggle. A screen gives it isService, which usePeopleDirectory supplies.

2.13.4. Entries that are one act

A bulk import writes a record for each row, so the history of one party can hold forty links created in one second. The rail draws entries that are one act as one row that opens to its members.

  • ES-HIST-19 Entries are one act when they were created, or closed, by the same author, for the same kind of record, with the same reason code and the same comment, and each follows the one before it by no more than 5 seconds. There must be at least 3.
  • ES-HIST-20 A change is never part of a batch. It carries a difference that a reader wants to read.
  • ES-HIST-21 The batch row says what was done once: the kind, the count, the kind of record, the reason, the author and the comment. Beneath it, "{n} entries" opens a list of the members, one line each, with the time and the name of the record.
  • ES-HIST-22 The batch stands at the time of its newest entry. Entries of other acts keep their place around it. A batch has no Revert button.
  • ES-HIST-23 The chart and the counts still read the entries. A batch is only how the rail draws them.
  • ES-HIST-24 A party history leaves out its versions that changed none of the fields it carries, such as the versions a child record's import bumped. The first version stays.

2.13.5. Links

A party works in countries and currencies, and may trade with counterparties. A person works in parties. Each of these is a link, and the timeline draws a link as a record of its own.

  • ES-HIST-25 A link is named by what it points at: "Country GB", "Currency EUR", "Counterparty Globex Corporation". A counterparty or a party is said by its name, and its id stands only when the name cannot be read.
  • ES-HIST-26 The opening of a link is a "Created" entry. A change to a link, where it has a column of its own, is a "Changed" entry with the difference.
  • ES-HIST-27 The closing of a link is a "Closed" entry. It carries the time the link ended and the account that ended it, drawn as the author of any other entry is. A link closed before the store recorded the closer has no author, and the entry does not say that it has none.
  • ES-HIST-28 A link that was closed and opened again is one record in two runs. The second run counts from one again.
  • ES-HIST-29 The timeline names a gap for a kind of link only when that kind could not be read. A kind that read and holds no link states nothing.

2.13.6. The author

  • ES-HIST-30 The author's photo stands at the left of the entry, beside the header and the changes, at medium size (2 rem) so that a face can be seen. Where the author has no photo, their initials stand in the same circle. A service is its initials.
  • ES-HIST-31 The author's name is a link to their page where the reader may open people. A service is text.
  • ES-HIST-32 The photo and the link come from the same directory as every other mention of a person.

2.13.7. One rail for several kinds of record

A person's history merges the versions of the account and the contact record, the roles given, and the sign-ins. They share the rail, and each entry names its kind and its record.

  • ES-HIST-33 Each kind of entry has its own tone: a change, a grant, an act, a decision.
  • ES-HIST-34 An act that is not a version, such as a sign-in, is drawn quietly and says that it cannot be reverted.
  • ES-HIST-35 A version of a record that may be reverted offers Revert to the person who may write it. The newest version says "Current version" and offers nothing.
  • ES-HIST-36 Entries are paired with the version before them to find what changed. The pairing is the screen's reading of the stream, not the server's claim.

2.13.8. Gaps

Some parts of a story cannot be answered, and the stream says so. A grant that was taken away is closed and no read returns it. The sign-in log keeps a window. Each such part is a gap on the answer, stated on the screen in words. A gap is never rounded away, and it is never shown as an empty list.

  • ES-HIST-37 A gap the screen knows is said in its own words, in every language, once.
  • ES-HIST-38 A part that was removed is closed, and no read lists a closed row. A party's history says so for its identifiers, its contacts and its business units, in its own words, until a read by parent lists them.
  • ES-HIST-39 Any other gap says that part of the history could not be read. It then names the record and gives the stream's own reason, so a reader can tell what is missing and why. The reason is in English and may name tables, reads and refusals. Such a gap is a fault to fix, not a state to keep.

2.13.9. How a part of a story is read

A history is read for one row. The screen names the row by its own id when its kind of record has one, because the key a model declares for the row may be shared by other rows: every party holds a contact of each type. A link has no id of its own, so its history is read by the parent it belongs to, and each version names its link as parent/child in its ID field. The screen pairs versions by that field. The rule for the request is in Entity addressing.

2.13.10. Narrowed histories

A history narrowed to one field, such as the reporting line, keeps every version in the stream so each is read against the one before, and shows only the versions where the field moved.

2.13.11. History and Audit

ES-HIST-40 History is the versions of one record, and the tab is named History. A log of events that happened is Audit, and has a Refresh and no revert. The sign-in record is Audit. In a person's timeline it appears as acts.

2.13.12. Relationship histories

A history that spans many subjects, such as who changed their reporting line, is two steps and not a merged rail.

  1. A list of the subjects for whom the thing changed recently, newest change first, each with the old value and the new one.
  2. The subject chosen from that list, drawn as its own narrowed timeline.

There is no card of the person beside it. The list is the way in.

2.14. Several kinds of record in one entity

  • ES-ASPECT-01 One page per subject. An aspect is a tab, not a screen of its own.
  • ES-ASPECT-02 Each tab reads what it needs, and each read is its own permission. A reader who can read an account and not its roles sees the Details tab and not the Roles tab.
  • ES-ASPECT-03 A reader sees their own record whatever they hold. The signed-in person's own account, contact record, sign-in state, sessions and permissions are self reads on the allow-list of Authorised reads. A page that is the reader's own uses them and needs no permission. Any other person's page needs the read of that aspect.
  • ES-ASPECT-04 When the read of one aspect is refused, that aspect says so and the others carry on.
  • ES-ASPECT-05 The entity's relationships are shown where the reader needs them: a manager on the identity card, the people who report to a person in the hierarchy, the parties as tags in the list.
  • ES-ASPECT-06 Do not add a tab to say that something cannot be done. Say it where the control would be.

2.15. A trade, a structure and a package

A trade is an entity made of several kinds of record, and it follows this page. The Trade journeys say what a person does with it. The Trades prototypes draw it.

2.15.1. The trade page

Tab Holds
Details The identity card, fixed for the life of the trade, and the booking card
Instrument The instrument the trade type routes to. One card for its terms, and one for each child table: its legs, its premium, its exercise prices
Identifiers and roles The identifiers, the party roles, the portfolios and the additional fields
Links The structure or package the trade is in, and the trades it is linked to
History The timeline
  • ES-TRADE-01 The identity card says why a field is fixed. The party and the counterparty never change, so a change to either is a cancel and rebook, which is a lifecycle event and not an Edit.
  • ES-TRADE-02 Edit asks for the kind of change first, and the kind bounds the fields the dialog offers. This is the rule of Trade Versioning: the reason constrains the change. The dialog then says what the save will do, which version moves and whether a confirmation is issued.
  • ES-TRADE-03 A trade that is the leg of a structure or a package says so, and says whose confirmation a change reaches.
  • ES-TRADE-04 Recording a lifecycle event is a workflow, in the Workflows menu of the page. It has steps and writes several records, and a novation books a second trade.

2.15.2. Booking a trade

Booking is the Add of the trade list. It opens a page and not a sequence, because a sequence is allowed only when it makes the task quicker, and a trader booking a deal knows the whole deal.

  • ES-TRADE-05 The page has four tabs: Trade, Instrument, Identifiers and Review. Book is a button in the header and stays disabled until the review has nothing to refuse.
  • ES-TRADE-06 The trade type is a combo box, grouped by product. A trade type with no instrument table is listed and cannot be chosen, and says so. The type is the one choice that decides what the Instrument tab holds.
  • ES-TRADE-07 The Instrument tab has a tab of its own for each part of the instrument: its terms, then each child table. A part with rows is edited as a table with Add a row and Remove. A part that the economic digest does not read says so where the person edits it.
  • ES-TRADE-08 A trade booked in a virtual book must be a draft, a test or a hypothetical. The Review tab refuses anything else and says why.

2.15.3. A structure and a package

A structure is a tree: the deal the customer sees at the root, with strategies, packages and trades inside. A package is a structure of kind Package, so there is one screen and its words follow the kind. See Trade Structures and Deal Composition.

  • ES-TRADE-09 The tree is its own panel beside the page, as in the structure editor. A row stands for the root, for each inner structure with its kind, and for each trade with its product, role and notional. A click on a structure opens its page, and a click on a trade selects it.
  • ES-TRADE-10 The page says how the kind confirms and prices: a strategy, a typed structure and a dynamic structure are one deal, and a package confirms trade by trade.
  • ES-TRADE-11 The list shows each root with its inner structures indented under it.
  • ES-TRADE-12 Grouping trades is a workflow, because the kind to choose has consequences the person must read first.

2.15.4. A priced structure

The price of a structure is a tab of the structure page. There is no separate workbench that edits a structure in place.

  • ES-TRADE-13 The members of a structure change through the Edit pattern, one change at a time. A dialog asks for the reason and the commentary. The change waits until the person presses Refresh, and the history of the structure records who made it and why. A change to the members does not move the version of a trade.
  • ES-TRADE-14 A leg is booked on Book a trade, with the structure and the role in the address. The booking and the membership are two writes. The result offers the next open role of the template.
  • ES-TRADE-15 A strategy states what its template asks of its legs, and the Members tab shows each check as it passes or fails.
  • ES-TRADE-16 Market data is a snapshot, and the tab says when it was read. A newer snapshot turns Refresh gold, and nothing ticks by itself. A screen that must stream says so on its own query, as the notification bell does.
  • ES-TRADE-17 A price is indicative. The tab says so, and it names the shifts that were applied.

2.16. The entity protocol

A screen of an entity reads and writes through the standard entity operations of the NATS entity protocol specification, and invents no message of its own. What a screen needs from the server is stated as a change to the entity's model, and not as a new operation.

  • ES-PROTOCOL-01 Reads. A list is list with an offset, a limit, a stated order and a filter record. The reply carries the total, and the pager is built from it. A record page is get. A set of rows for the keys on a page is get_many or a filter with a one-of member. A history is list of the entity's versions. A read at an instant is the as_of field.
  • ES-PROTOCOL-02 The filter record. A filter has an equals member for each column the model declares filterable, a one-of member for the key and the relation columns, a _from and a _to member for each filterable date or timestamp column, and one search member for the columns the model declares searchable. A screen that wants to filter by a column asks for the column to be declared filterable. It does not filter in the browser. A combo box that filters a list offers only the values that exist, as the paging section says.
  • ES-PROTOCOL-03 A scoped read. The children of one row are list_by_<relation>, such as the identifiers of a trade. A filter on a column of another entity, such as the trades in a book or in a state, is a filter of a read model that carries the column, and not a join the screen builds. The trades of a portfolio and the portfolios below it are the books below it, read first, then a one-of member of those books. The table in Finding an entity of the protocol specification names the mechanism for each need.
  • ES-PROTOCOL-04 Writes. A change is put with a precondition, which is the version the edit started from, and a change intent: the reason code and the commentary. A set of records is put_many, and it is one transaction. The screen never sends a tenant, a party, a version it computed or a provenance field.
  • ES-PROTOCOL-05 Domain operations. A write that touches several entities as one transaction, such as booking a trade, is a domain operation in the ops namespace of its component. It is the exception, and a screen uses one only when the common verbs cannot do the job. Each use is listed on the journey as a gap to review.
  • ES-PROTOCOL-06 Events. The change news of a screen is the entity's events. The screen names the entity it shows and never guesses a subject.
  • ES-PROTOCOL-07 The registry. Each entity declares itself once, as the record standard says, and the screen reads the declaration. A trading entity gets the same kind of registry entry, write schema, field table and column list as a reference data record.

2.17. Relationship views

A tree, a chart and a queue draw how subjects relate.

  • ES-RELATION-01 A tree draws each subject once, under the subject it relates to. A subject can belong to several groups, such as a person in two parties, and is then drawn in each group, with the same person under the same manager in each.
  • ES-RELATION-02 A group is a party, nested by its own parent, and its name is drawn, never its code.
  • ES-RELATION-03 A filter by group appears only when the reader sees more than one, and its choices are the groups they see.
  • ES-RELATION-04 A person with a manager the reader cannot see is marked, not drawn as a root.
  • ES-RELATION-05 A chart zooms and fits, and scrolls sideways rather than squeezing its cards.
  • ES-RELATION-06 A relationship view is paged or lazy in the same way as a list. It never reads every row to draw the part the reader sees.

2.18. Who sees what

Visibility is decided by the narrowest read that does the job.

Reader Sees Through
A tenant administrator Every subject of the tenant The read of accounts
A member The people in the parties they work in, and everyone who reports to them The organisation read, scoped by party and reporting line
Anyone Their own record Self reads
  • ES-SEES-01 A member's list shows names, photos, titles and parties. It does not show email addresses, contact records, sign-ins or roles. Account data is not screen furniture.
  • ES-SEES-02 A party the reader does not work in, and does not manage someone in, is not named to them, even when a colleague in their own party also works in it.
  • ES-SEES-03 A person who is outside the reader's view is "someone outside your view", never an identifier.
  • ES-SEES-04 The menu offers an entry by the narrowest read that screen needs, so a member gets Staff and Hierarchy and an administrator gets the fuller list.

2.19. Proposals and four-eyes

A change that another person must agree to is a proposal, not a write.

  • ES-PROPOSE-01 The control says Propose, and the dialog says that nothing changes until the other person approves.
  • ES-PROPOSE-02 The proposer sees the state of their proposal among their own requests and can withdraw it while it waits.
  • ES-PROPOSE-03 The person who decides sees it in Requests, with who proposed it and what changes, and approves or declines it. A decline needs a comment.
  • ES-PROPOSE-04 Requests is the one place for every kind of request. Every member sees their own there, and a person who can decide also sees the queue.
  • ES-PROPOSE-05 The decision and the apply are recorded, so the history of the subject names the proposer, the decider and the time.

The reporting line becomes a proposal in the story "Approve a reporting line change by the proposed manager". Until that story is done, the line is changed by a direct edit for those who hold the update permission.

2.20. The shell around a screen

  • ES-SHELL-01 The footer states the tenant and the party the session acts for, as pills, because they decide what every screen shows. It also states the client, the server and the environment.
  • ES-SHELL-02 The header names an administrator's mode and says nothing for an ordinary member, whose mode has no meaning to them.
  • ES-SHELL-03 The notification bell and the account menu stand in the header. The account menu holds the person's own pages and signing out. It is not part of the menu of areas in Menu structure.
  • ES-SHELL-04 A person's own pages are My profile, My access and Where I work. They are reached from the account menu and from the profile's doors, each in one place.

2.21. Feedback, states and words

  • ES-WORDS-01 A screen states what it is waiting for. First load says "Loading…" in the place of the content. A reload keeps the rows, dimmed. An empty list says what is empty and what to do. An error is in place, in the server's words, with Retry.
  • ES-WORDS-02 A refused read is a refusal and not a failure. The screen says the reader may not see this, in words, and never shows a permission code.
  • ES-WORDS-03 A time is relative with the exact time on hover. "Never signed in" is a phrase and not 1 January 1970: a missing time is not a time, the server states null for it, and no screen has a zero instant to explain.
  • ES-WORDS-04 Words are in sentence case, and the verbs are the Record screen standard's Naming list, which includes Propose. An entity's own action is a verb and its object.
  • ES-WORDS-05 Every string exists in English, French and Portuguese before the screen ships.
  • ES-WORDS-06 A screen never shows an identifier where a name would do.
  • ES-WORDS-07 A screen does not narrate what is absent. A control that is not offered is not drawn, and nothing says why unless the reader would otherwise be stuck. A sentence that only explains an empty space is removed.

2.22. Updates and refresh

A screen learns that the data under it changed, says so in one place, and waits for the reader. Nothing reloads by itself, and nothing that the person typed is lost. The design is in Change notification; this is what a screen must do.

2.22.1. How a screen hears

  • ES-REFRESH-01 The browser holds one stream of change news for the session. It opens when the first screen watches something and closes with the last, so a screen that watches nothing holds no connection.
  • ES-REFRESH-02 A screen names the entities it shows, as the services name their events: the component and the events collection, such as iam and accounts. The refdata registry states these, so no screen guesses a plural.
  • ES-REFRESH-03 The news is a time and not a list. A thousand changes in one import make a screen stale once.
  • ES-REFRESH-04 The news may name the records that changed, when there are few (up to 20 in one message). A list uses them to place the change (see Refresh). A record page names its record in its watch ({ component, entity, record: { username } }) and goes stale only when the news names its record or names none. It does not pulse for another person's change. A page that cannot state its record's key leaves the record out and goes stale for any change to the entity.
  • ES-REFRESH-05 A screen is stale when a change reached the browser after the load that produced its data began. The comparison uses the browser's clock at both ends, because the server's clock differs. A change that arrives while a load is in flight counts.

2.22.2. Refresh

  • ES-REFRESH-06 Every list, relationship view and record page has a Refresh button in the header's actions, the same control and the same place (RefreshButton).
  • ES-REFRESH-07 When the screen is stale the button turns gold, pulses four times, and stays gold until the screen loads again. Its tooltip says the data changed and gives the time. A reader who asks for less motion gets the gold and no pulse.
  • ES-REFRESH-08 The gold (--color-stale) means "changed on the server" and nothing else.
  • ES-REFRESH-09 A list also says where the change fell, in three cases. The list keeps the records that the changes since its load named.

    1. A few records, all on the page: those rows pulse (row-news).
    2. Too many to name, or a list that cannot tell its rows apart: a strip along the top of the table says that something changed which the page cannot show.
    3. A record on another page: the same strip, because no row on this page can carry the mark. When a change names rows on the page and also a record off it, the rows pulse and the strip shows.

    A list tells its rows apart by recordKey, the key of the record a row shows, as the events name it. Refresh stays gold in all three cases.

  • ES-REFRESH-10 A click reads again whatever the screen shows. On a record page that is every card and the history.
  • ES-REFRESH-11 The page does not reload by itself. A list does not, a record page does not, and the history does not.
  • ES-REFRESH-12 The query client holds this for every screen. It never reads again because the window gained focus or the network came back (refetchOnWindowFocus and refetchOnReconnect are off). A screen that must poll says so on its own query, as the notification bell and the dashboards do.
  • ES-REFRESH-13 A tab of a record page that the person has opened stays drawn and is hidden while another is open. Leaving a tab never unmounts its reads, so coming back to it reads nothing. A tab the person has not opened reads nothing.
  • ES-REFRESH-14 Refresh reads again only the queries the page shows: the record, its parts, its links and its history. It does not read every record of the app.
  • ES-REFRESH-15 A save does not reload the page either. The save's own change event makes Refresh gold, like any other change, and the person presses Refresh to see the saved values. A page that was reloaded by the save would hide that the data moved, and would make the gold mean two things.

2.22.3. When the data was loaded

  • ES-REFRESH-16 Under the Refresh button the screen says when it loaded, as an ISO 8601 timestamp in the reader's zone, such as 2026-10-11T02:13:10+01:00. It is small, monospaced and faint (half opacity), and it has no label. The tooltip says "Loaded" and repeats the timestamp. The text is the same in every language.
  • ES-REFRESH-17 The timestamp is part of RefreshButton, which takes the screen's load state and the news about it, so a screen cannot show the button without it (LoadedAt).
  • ES-REFRESH-18 The time is the browser's clock at the moment the data arrived. It is the clock the stale logic compares, so the two never disagree. It is not the server's as_of, which is a field a caller sends to read the data as it was at an instant. A read response carries no read time.
  • ES-REFRESH-19 A screen made of several reads states the oldest of the reads on screen, because the screen is only as fresh as its oldest part. The stale logic uses the newest, which is a different question. Only the reads the screen is showing count: a page of a list that was read earlier stays in the cache and does not age the screen.
  • ES-REFRESH-20 The time stays while a reload runs or fails, because the old data is still on screen. Before the first load nothing is drawn.

2.22.4. Rows and entries that changed

  • ES-REFRESH-21 After a reload, a row that was not on the page before, or whose content is not what it was, gets a gold left edge and pulses three times. The mark goes after four seconds. The list keeps its scroll position.
  • ES-REFRESH-22 The comparison is with the same page read before. It uses no clock, and moving to another page, searching or sorting marks nothing.
  • ES-REFRESH-23 A history entry that arrives with a read is marked the same way.

2.22.5. An edit in progress

  • ES-REFRESH-24 A dialog is never reloaded under the person. While it is open it listens for a change to its entity and reads the record again behind the form.
  • ES-REFRESH-25 When the record is newer than the one the edit started from, a warning above the form says who saved it and which fields moved, with the old and the new value. The person chooses Keep my edit or Take the new values.
  • ES-REFRESH-26 A save claims the version the edit started from. A save made against an old version is refused with a clear message, and the edit stays in the form.
  • ES-REFRESH-27 Keep my edit makes the newest version the base, so the save replaces it knowingly.
  • ES-REFRESH-28 A dialog over a record says under its title when the record it started from was loaded (Dialog's loadedAt). The time moves when the person takes the newer version or keeps their edit on top of it, because the base has changed. A dialog over no record leaves it out.

2.22.6. What is not heard yet

  • ES-REFRESH-29 The events of another tenant are not told to a session. An event names its tenant and, on a party-owned table, its party, in the envelope. A session hears its own tenant and the system tenant, and a member hears the parties they work in. The broker does not enforce this, so a client that listens to NATS directly still hears every tenant.
  • ES-REFRESH-30 A role granted or taken away is published inside the service only, so a person page cannot hear it.
  • ES-REFRESH-31 A reporting line has no event of its own. The staff list and the hierarchy hear it when the person changes too.
  • ES-REFRESH-32 A change to a record that a screen shows by reference, such as a country name on a book, is not heard.
  • ES-REFRESH-33 The classification lists, the staff list and the hierarchy mark no rows yet.
  • ES-REFRESH-34 The account profile write has no version claim in its protocol. The BFF checks the claim just before it writes, which leaves a very small gap.
  • ES-REFRESH-35 The notification bell still reads its count on a timer.

2.23. What a screen or a form needs, and what the log keeps

A screen or a form that is drawn must work. So what it needs is known before it is entered, and a screen the reader cannot use is not drawn.

  • ES-NEEDS-01 Each screen and each form declares what it needs, as typed permission constants (access/permissions.ts, access/screens.ts). A wrong name does not compile. The menu, the home tiles, the route guard and the button that opens a form read that one declaration.
  • ES-NEEDS-02 A screen the reader cannot use is not offered. A saved link to it does not show "not available". It names the screen, says in words what the reader would need to be able to do, and lists the roles they could ask for that allow it. Each has a link that opens the request for that role, already filled in. When no role can be asked for, it says to ask the tenant administrator and offers no link. The words for each permission are typed, so a new permission without words does not compile.
  • ES-NEEDS-03 A screen that was drawn and then refused a read is our fault, not the reader's. It is replaced by a panel that says so, gives a reference that finds the request in the log, and offers Try again and Home. The roles are read again first. If they changed, the screen's own guard takes over and says what is missing.
  • ES-NEEDS-04 Nothing is decided until the roles are known. Requires and FirstAvailable draw nothing but "Loading" while the roles are read, so a screen never asks the server for what the reader may not read.
  • ES-NEEDS-05 Two audiences are two screens. The whole directory and the people of your own parties are two screens, each with its own declaration. A screen does not inspect permissions to decide which screen it is.
  • ES-NEEDS-06 A form saves through one hook (useRecordEdit): save, close the form, and mark what the save changed as out of date. The hook reads none of it again, because a save does not reload the page (see Refresh). The person reads again with Refresh, which the save's own change event has turned gold. A read that no screen shows is stale all the same, so the screen that shows it next reads it fresh.
  • ES-NEEDS-07 Every failed request names its operation (the method and the path, with no query), its status, the server's code, and the request id. The banner shows the operation and the first eight characters of the id. The BFF puts the same id on its own lines for that request.
  • ES-NEEDS-08 The path a person took is in the log. The browser sends a trail to the BFF: screen entered, screen left, form opened, form closed, save requested, saved, save refused, save failed, request failed. The BFF writes each in the line form of the services, under ores.web.client.<area>, with the session id: time [LEVEL] [logger] message key=value. A search on the session id follows the person through the browser, the BFF and the services. The trail holds no value a person typed and no secret.

2.24. The shared components

Rule Component Status
A reference to any record The reference mechanism of the story "Link every reference to its record" Planned; each screen builds its own address today
A person named in text PersonRef and usePeopleDirectory in access/PersonRef.tsx Exists; the directory is read whole, see the deviations
The author's picture useActorPictures in access/PersonRef.tsx, Avatar in ui/Images.tsx Exists
A history author's link actorPathFor in access/PeoplePage.tsx Exists
The timeline Timeline in timeline/Timeline.tsx Exists; one-line headers, details on demand, the event chart, the author's photo beside the header, the author's link, the current-version emblem
A person's merged story readPersonTimeline in wire-protocol/src/timeline.ts Exists; reads the whole account history, see the deviations
A party's merged story readPartyTimeline in wire-protocol/src/timeline.ts, drawn by Timeline with recordName Exists; the party, its identifiers, its contacts and its business units, with the junctions stated as gaps
The pager Pager in ui/Pager.tsx Exists
The roles panel, paged on the server RolesAllow in access/Allowances.tsx, list_account_permissions and list_my_permissions Exists
The role editor, paged on the server RoleEditor in access/RolePage.tsx, list_role_permissions Exists
The roles list, paged on the server RolesPage, list_roles_page Exists
The holders of a role, paged on the server RolePage, list_role_holders Exists
The organisation tree, by party ReportingLinesPage, OrgChart, organisation.ts Exists; reads the whole tree, see the deviations
A member's list of staff StaffOfMyParties Exists; reads the whole organisation read
Self reads get_my_account, get_my_login_info, get_my_sessions, list_my_permissions Exists
Links for email and web mailto and webLink in access/PersonForms.tsx, Detail in ui/Primitives.tsx Exists
Tenant and party in the footer VersionFooter Exists
The workflows on an entity screen WorkflowMenu in shell/WorkflowMenu.tsx, workflowsOn in shell/cards.ts Exists on Parties; the other entities have no workflow yet
Refresh RefreshButton in ui/RefreshButton.tsx Exists; gold and pulsing when stale
The change stream EntityEventStream, EntityEventsProvider and useEntityChangeEvents in events/ Exists
Knowing a screen is stale useEntityChanges and useLoadState in events/ Exists
Marking rows that changed useChangedRows in refdata/changedRows.ts, the row-changed class Exists
An edit that learns of a newer version useNewerVersion and NewerVersionNotice in access/newerVersion.tsx Exists

2.25. How the Staff screens conform today

Rule Where Staff differs
Server paging for everything The person's timeline reads the whole account history and merges four reads. It needs a window and a load-older control
Server paging for everything The roles a person holds are read with every permission code of every role. It needs a paged list of grants without the codes
Server paging for everything "Can I…?" searches the whole permission catalogue in the browser. It needs a server search
Server paging for everything The directory behind PersonRef reads the account list or the organisation tree whole. It needs a lookup of the few identifiers a screen draws
Server paging for everything The organisation tree for the Hierarchy is one read of the whole visible tree. It needs branches read on demand
Server paging for everything The staff list for a member is the organisation read, sorted and searched in the browser. It needs the same server search and paging as the administrator's list
Words The person page names its history tab Timeline and My profile names it History. One name, History, is the rule
Photos A history author's photo comes from the directory, so an author the reader cannot name is shown as initials, and the directory is read whole
Proposals The reporting line is not yet a proposal
Updates Only the person page has a Refresh that hears changes. The other record pages need the same with their own watches
History A party's history reads every version of every part and link at once, one read for each row, with no window and no load-older control

Each deviation is a follow-up. None of them is a reason to copy the shortcut to another screen.

2.26. Building an entity screen

Work in this order. Each step ends in something to check.

  1. Name the subject, its aspects, and for each aspect the table, the read and the permission. Say which aspects the reader sees whatever they hold.
  2. Decide the list: its columns, its search, its filters and its default order. Say what the server searches and sorts.
  3. For every read the page will make, write down its page: its offset, its limit, its total and its filters. If a read has none, it is not ready.
  4. Add the self reads the signed-in person needs, and put each on the allow-list of Authorised reads in the same change.
  5. Build the list from the shared parts, then the page: header, tabs in the address, one card per changeable aspect.
  6. Put Edit on each card, with the reason in the dialog. Give the list a Workflows menu if any workflow acts on the entity, and register each workflow against the screen it acts on.
  7. Draw every person with PersonRef, every email as mailto:, every web address as a link, every flagged code with its flag.
  8. Build the timeline from the shared Timeline: headers, details on demand, author photo and link, gaps stated.
  9. Add the strings in English, French and Portuguese.
  10. Check it against data of the real size, as a member and as an administrator: a large tenant, a role that grants a whole area, a person with no photo, a person outside the reader's view, a refused read, an empty history.

2.27. Verifying a rule

ES-VERIFY-01 A rule is done when the screen shows what the rule says, tried against data of the real size, as a member and as an administrator. A test that checks only the code's own reading of the rule is not enough. The Staff work paged the areas of the permissions in the browser, passed a test of that, and still showed a screen with every permission on it.

3. See also

Emacs 29.3 (Org mode 9.6.15)