People

One door for the team and the contacts, because splitting them is the org chart this app refuses. Roles are hats: no screen is gated by a role name, capabilities gate actions, and a capability you lack is visible and inert rather than missing.

1 · The team, which is two people
Not because the company is small in an apologetic way, but because the segment is. Six starts a year with two or three people total is the center of the market, not its tail.
Two capabilities apart, not two tiers apart

Renee holds eleven of thirteen. She drafts change orders, settles decisions, writes quotes, invites people and reports contract figures. The two she does not hold are both money-with-consequences: voiding a signed amendment, and changing what somebody else can do.

Twelve rows, thirteen capabilities, and the count used to be the only place two of them existed

This table drew ten rows and said thirteen, and DB_DIAGRAM.md §8 item 10 recorded three as counted-and-not-named. The arithmetic was off twice: the first row is two capabilities, not one, so ten rows carried eleven — and the genuinely absent pair was two. They are here now: reading and answering the homeowner, which is every thread, ask and digest on the page, and putting a sub on a job. Both are on by default, which keeps frame 5's eleven of thirteen are never in question true.

There is no money-management capability at any level

Not for Dave either. Allowances are the homeowner's, he reports and she confirms, and nothing he writes is money she owes until she says so. A builder-side set the allowance button would quietly move the whole product's center of gravity.

And no screen is gated by a role name

Renee sees this page, sees both controls she cannot use, and sees why. There is no admin view and no owner view — one app, and the two rows above are the whole of the difference.

2 · Contacts — one list, one shape
Subs, vendors, homeowners, inspectors, lenders. Nothing here is a kind of user, nothing here has a login, and nothing on a row says whether the person has an account.
Sam is on this list, and so is Luis

A homeowner and a tile setter, in one list, in one shape. Filing them separately is where sub starts turning into a kind of user, and the moment it does, somebody builds a sub login and a sub dashboard and the account-less tier grows a second class in it.

Nothing says who has an account

Sam does, Ben does not, and the rows are identical. An account is a badge on a person and it is not this product's business to display it — a year later the record must not be able to tell the two paths apart and must not care.

And there is no invite here

Add a contact and add somebody are different verbs on different lists. A contact is somebody you deal with; a seat is somebody who holds part of your subscription. Merging them is how a builder accidentally gives his tile setter a login.

3 · One contact
What the product knows about a person: how to reach them, which jobs they are on, and what has passed between you. Not a profile, and not a portal.
The one place the tier is mentioned, and it is for Dave

Said once, on the builder's own screen, so he does not go looking for a login to send. It is a fact about how to reach somebody — the same register as the phone number above it — rather than a status on a person, and it never appears on a row, a chip or a name anywhere else.

Between you is the register, filtered

Not a message thread. Every row is half of a send, including the one that could not be routed, and the unrouted reply is as visible here as it is in Send — because a reply path that hides its failures is a reply path that lies.

Responsibility belongs to the job

The same contact can cover different work on two projects. Rooms and Systems are assigned here, on the project, and stay editable; they are not inferred from workstreams or stored as a category on Luis.

4 · Adding a contact
The screen behind Add a contact. Four identity fields, and none of them is a kind of person. The project-scoped section below says where Luis is working and what he covers; it never makes him a user.
No category field, and that is the page's whole argument made concrete

Frame 2 says subs, vendors, homeowners, inspectors and lenders are one list and one shape. A type dropdown here would undo that in the one place it is easiest to add and hardest to remove — the moment a contact has a category, somebody filters by it, and the subs tab this page refuses arrives by the back door.

A trade is typed, not picked

There is a trade column on six tables today and no shared vocabulary behind any of them. A picker would have to invent that vocabulary and then be wrong for somebody — tile setter, tile and flooring are the same person at three companies. Free text is the honest shape until a real list exists.

One required field

The number. Everything the product does with a contact is a send and a reply, so a contact with no number is a note about a person rather than a person the app can reach. The other three are conveniences and the screen does not pretend otherwise.

Typed scope, on two existing axes

Q6 ruled that People are typed by hand rather than inferred. Rooms handle a cabinet installer on two spaces; Systems handle an electrician across the whole house. A contact with both matches work only where both axes meet.

5 · Sending an invite
The screen behind Invite somebody on frame 1. It sends an invitation, not a half-seat: the person becomes a seat only after they accept from their own email.
Two switches, not a role

The alternative was Owner and Member, and it is wrong for a company of two: a tier makes somebody a lesser kind of person, and the difference here is two specific acts with money behind them. Naming the acts is also the only version that stays honest when a third capability becomes contentious — a tier absorbs it silently, a switch has to be added and argued.

Both default off, and the caption says why rather than what

Unwinding money both sides have agreed to is what the switch does; void_change_order is what it is called. The field rule in forms.css is explicit that a hint explains the ask and never the format, and a capability's hint is the same problem — the reader is deciding about a consequence, not a permission name.

This is the builder side and it has a permission model

Which is not a contradiction of mockup 14. Two people who live in the same house are peers by definition; two people who work at the same company are not, and one of them signs the contracts. The homeowner invite has no switches at all, and neither screen borrows the other's shape.

6 · Putting the client on a job
The screen behind Invite to this job on a job's page. Frame 5 seats somebody at the company; this seats somebody on one house, with the house's own seat, and asks the one thing the product cannot work out for itself: whether this is the person whose house it is.
Asked, because it cannot be inferred

The builder's own seat on a job is the house's owner seat too, and a colleague can be given one. Nothing about a seat says client, and every rule that guessed from seat history was wrong for somebody: a client who once worked for the builder, or staff who only ever held owner seats. Q298 ruled that the builder says so here, once, per invite.

Neither is picked when the screen opens

Drawn with the first chosen so both states show. On arrival neither is, and Send invite stays off until one is: a default would be the guess again, made by the screen instead of the server. An invite sent without an answer — one from before this screen existed — never files the house under anyone.

The captions say what follows, not the mechanism

What the answer drives is which household the house joins (HOMEOWNER_MEMORY_DESIGN §3), and that word is nowhere on a builder's screen. The house is Nora's is what a builder can answer without knowing it; the seat and what it can do are identical either way. The captions promise nothing about what the product learns: that is the homeowner's disclosure (AN6), not the builder's to describe.

7 · An invite that is out
The screen behind an invite row: Nora's under On this job on a job's page, or Marco's under Invites sent on frame 1. Until somebody accepts, the builder can still change the answer frame 6 asked for, or call the invite back.
A wrong answer is fixed before it counts

The answer does nothing until Nora accepts, so until then it is only words on the invite and the builder can change them. Drawn mid-correction: the invite says works with you, Dave has tapped is the client, and Save answer is on because the two differ. It is off when they match. Nora is not emailed again; she never sees the answer.

After she accepts, the answer stands

Accepting is when the house is filed (Q298), and this screen stops existing for her: she is a seat, not an invite. A house filed on a wrong answer is corrected by removing that seat and inviting again, which asks frame 6's question afresh. Moving a house out of a household is AN5's to design, not this screen's.

Cancel is for any invite that is out

Marco's company invite on frame 1 opens this same screen without the question, because a builder seat has no answer to give. Canceling ends the invite for good: the link refuses, the row leaves the list, and inviting the same address again is a new invite with its own answer. Owner invites never expire, so without this a wrong one would sit there until somebody accepted it.

Only for somebody who could have sent it

Changing the answer or canceling asks what sending that invite asked (Q122): an owner invite needs what the house's owner seat holds, and a company invite that chose what somebody can do needs Change what somebody can do. Renee can cancel an invite she could have sent, and no other.

Why there is no subs section

Sub is a relationship, not an identity. The builder research and the identity spec reached that independently — the first says of subs no login, ever, the second says an account is a badge on a contact rather than a category of user. A subs tab creates a class of person, a class of person acquires its own screens, and within two releases there is a sub dashboard nobody asked for.

The shipped code still carries a subcontractor role with exactly one capability. Under the backend is not a constraint it is a deletion rather than a migration, because there are no production accounts — and it is the one place this design knowingly contradicts what runs today.

One word, and it is the identity spec's

The builder research says touchpoint; the specs say account-less, and they mean the same person. Account-less names the fact rather than the relationship: a homeowner is not a touchpoint of anything, and the tier is a property of the person rather than of the side they are on.

What is not here

An org chart, a title field, a department. Roles are hats: at the median the person signing up is the owner, the estimator and the project manager on the same afternoon, and asking him to model a company he is is the configuration week the product refuses.