What gets mounted
Three mounts, and no others.
All of a caller’s orgs are mounted at once. There is no active org and nothing
to switch —
/orgs lists exactly what this request’s memberships seam
asserted, and it is absent entirely for a caller who belongs to nothing.
A scratch directory inside /user or any org mount is working space that is
never committed.
Ownership is the path
The owner of a path is read off the path itself: the first segment under/orgs
is the org id, and everything else belongs to the caller.
Nothing is transferred and no row moves when someone leaves, because there was
never a pointer to their subject to update. That is what makes the tree survive
people.
The org id is one path segment, so an id containing
/ is unaddressable. Keep
the org string you assert free of slashes.Who may read and write where
An asserted membership for that org is the precondition. Without one, the answer is no — a path naming an org you are not in is refused before any rule below is consulted. Past that, three rules decide:- An app’s subtree defers to that app’s grants. Under
/orgs/<orgId>/apps/<appId>, access is whatever Sharing says it is, root row included. policy.jsonis members-read, admin-write. Every member of the org may read/orgs/<orgId>/policy.json; only a member you asserted withadmin: truemay write it. See Org policy.- The rest of the mount belongs to the membership. Outside app subtrees and
outside
policy.json, any asserted member of the org may read and write it.
Members only
An outsider is not told an org exists. Reading a path in an org you have no membership for fails the same way a path that was never written fails:forbidden to an outsider would be an existence oracle for every
org app id.
Two people, one file
Org paths commit under compare-and-swap. The turn remembers the revision it opened each file at, and the commit lands only if that revision is still current. A conflict is a returned status, not a thrown error:/user writes down with it. /user itself is last-write-wins — a
private file has no second writer to race.
The shipped surface says this in plain words when a generated app loses the race:
“The save did not land — someone else changed this app. Save again.”
When someone leaves
Drop them from your own roster and their mount is gone on their very next request. There is nothing to propagate. Erasing that person leaves the org’s tree standing, because none of it was ever theirs — see Erasing a user.Where to go next
Sharing
The grants an app subtree defers to, and the three principals they name.
appAccess(store).grantOrg policy
The one file in the mount an ordinary member may read but not write.
/orgs/<orgId>/policy.jsonPersistence
Where these files actually land, and what the store refuses.
vendo_apps