A kitchen of one is a kitchen
Everything belongs to a kitchen, and a kitchen with one member is a person cooking alone. A kitchen is a named place with people in it, a hob, a plan, a shopping list and a shelf of recipes.
From KITCHENS.md, One path, whether you cook alone or together
Sharing adds capabilities — join, switch, copy across — and forks nothing that already exists.
From KITCHENS.md, One path, whether you cook alone or together
One path, whether you cook alone or together
KITCHENS.md, the whole section
Everything belongs to a kitchen, and a kitchen with one member is a person cooking alone. A kitchen is a named place with people in it, a hob, a plan, a shopping list and a shelf of recipes. That is one path rather than two: a solo cook's kitchen is not a degenerate shared one, it is the same row with one membership, so every screen, every query and every fold runs the same code whether or not anybody else is in there. Sharing adds capabilities — join, switch, copy across — and forks nothing that already exists. The one place a second path could genuinely have appeared is measurement, and it is closed below.
A kitchen, not a library
Library is the right word for a shelf of recipes and the wrong one for everything else the same people share: a library does not shop, and it does not have a Thursday.
From KITCHENS.md, The tenant is the kitchen, not a library
The tenant is the kitchen, not a library
KITCHENS.md, the whole section
The tenant is the kitchen rather than a library, which is where this departs from the words the
requirement was written in. Library is the right word for a shelf of recipes and the wrong one for
everything else the same people share: a library does not shop, and it does not have a Thursday. The
grocery list, the meal plan and the hob are household facts and the recipes are the household's book,
so one entity carries all four — and read back as a sentence, only "kitchen" survives all four. The
code already pointed here: the ownership field was named ownerAccountId rather than ownerId
because a kitchen is joinable and a recipe could one day belong to one. What that foresight bought
was the shape — a tenant that is not a person — rather than the literal string, which now says
kitchenId because that is what it is.
What belongs to it
Ownership and authorship are different axes, and only one of them is the tenant.
From KITCHENS.md, Ownership, authorship, deletion and trust
Deletion follows ownership, not authorship — a delete is a household act.
From KITCHENS.md, Ownership, authorship, deletion and trust
MyTime is the kitchen’s. Two people who share a kitchen and cook from the same book get one figure between them: "if we are always sharing a kitchen and cooking the same recipes, my time should be essentially our time."
From KITCHENS.md, Ownership, authorship, deletion and trust
A kitchen is a trust boundary, not a privacy boundary between its members.
From KITCHENS.md, Ownership, authorship, deletion and trust
Ownership, authorship, deletion and trust
KITCHENS.md, the whole section
Ownership and authorship are different axes, and only one of them is the tenant.
Recipe
- Owned by — which rows are these
- the kitchen
- Authored by — whose evening, whose edit
- —
Recipe version
- Owned by — which rows are these
- the kitchen
- Authored by — whose evening, whose edit
- the cook who saved it
Meal plan
- Owned by — which rows are these
- the kitchen
- Authored by — whose evening, whose edit
- —
Grocery list
- Owned by — which rows are these
- the kitchen
- Authored by — whose evening, whose edit
- —
Cooking session
- Owned by — which rows are these
- the kitchen
- Authored by — whose evening, whose edit
- the cook whose evening it was
Cooking event
- Owned by — which rows are these
- the kitchen
- Authored by — whose evening, whose edit
- the cook whose tap it was
A note
- Owned by — which rows are these
- the kitchen
- Authored by — whose evening, whose edit
- the cook who wrote it
Ownership stays exactly one column, which is what keeps a store scoped to one id and keeps every key
reachable only by naming a tenant. Authorship is a second, weaker column that no query is scoped by —
and it is the column cooking_events.cook was already reserved for, arriving for group cooks and
doing this job on the way. A recipe carries no author, because the point of a shared kitchen is that
the book is the household's; a version carries one, because each edit is somebody's and a lineage
with no names in it is unreadable in a kitchen of two. A note needs no rule of its own: it is an
event, so it is written by a cook in a moment and readable by the kitchen, which is what the two
note-writing moments always meant.
Deletion follows ownership, not authorship — a delete is a household act. Removing a recipe is not scoped to whoever taps it, the way an edit is not either: the row belongs to the kitchen, so the kitchen loses it, and every other member's phone catches up on its next sync. Nobody's device is asked first and nobody's copy survives quietly. See ARCHITECTURE.md for what carries that fact between devices and how long it is kept.
MyTime is the kitchen's. Two people who share a kitchen and cook from the same book get one
figure between them: "if we are always sharing a kitchen and cooking the same recipes, my time should
be essentially our time." So the folds behind it read the kitchen's evenings and are filtered by
nothing — that covers MyTime, gatherYourDurations, and estimateStepTime's you tier behind
Details. The word the cook reads stays my time, because a household is the unit that word was
always describing.
This reverses an earlier design in which those folds took a required cook argument specifically so a
shared kitchen could not average two people. What survives the reversal is the stamp: cook is still
written onto every session and every event, and is simply never filtered on. That costs nothing now
and is the only thing that makes "show me just mine" possible later without a migration.
A kitchen is a trust boundary, not a privacy boundary between its members. Everyone in a kitchen can read everyone's sessions, evenings and notes; what they cannot do is have them counted as their own. That is the honest reading of wanting the recipe book entirely shared — a household that shares a book also wants to see that the dish was cooked on Tuesday, and what got written on the step. You join a kitchen with people you would hand your notebook to, and the way out is to leave rather than to hide a row.
Joining by invite
An invite is one link for everyone who is coming, and it works for a week. Owner ruling, 13 October 2026: one link the whole family can use for a trip, where it had been an hour and one person.
From KITCHENS.md, Invites, removing a member and who is the owner
Removing a member withdraws every link the kitchen has out (owner, 15 October 2026): a removed person cannot rejoin through a link they still hold, and the maker sends a fresh link to anyone still on the way.
From KITCHENS.md, Invites, removing a member and who is the owner
Invites, removing a member and who is the owner
KITCHENS.md, the whole section
An invite is one link for everyone who is coming, and it works for a week. Owner ruling,
13 October 2026: one link the whole family can use for a trip, where it had been an hour and one
person. Nothing is written when one is made, so it admits everyone who opens it until it expires and
cannot be taken back one at a time; why a week is invite-grant.ts's. Removing a member withdraws
every link the kitchen has out (owner, 15 October 2026): a removed person cannot rejoin
through a link they still hold, and the maker sends a fresh link to anyone still on the way.
A household's check on a leak is the member
list, and since the shelf shows each member's whole home book, a stranger let in by one sees those
too. Only whoever made the kitchen can remove another member (owner, 13 October 2026, asked
with the week-long link as the reason): the kitchen's first role, and removing takes
nothing the removed person made, as leaving does. The maker, whom the app calls the owner, is the first current member in ownerFirst's order
(libs/store-pg/src/kitchen-admission.ts), read and never stored as a role: whoever the kitchen was
last handed to (kitchen_members.owner_since, newest first), else the oldest. So a
kitchen never handed over keeps its oldest member, handing it over is one write (the owner's Make
owner, which also sets both members' roles to everything, so nobody loses what they saw and the new
owner sets the old one like any member), when the maker leaves it falls to whoever held it before them,
else the next-oldest, and a maker who rejoins comes back as the newest. A removed person's devices lose
the kitchen on their next request, because membership is read on every request. removeMember in
libs/store-pg is the one home, and the kitchens answer carries the maker as an optional flag on that
member so a screen never works the order out for itself.
SCREENS §12 is the card.