Use this skill for group creation, membership changes, manager changes, or explaining how _all and _admin work.
Canonical Group Tree
- Runtime-managed groups live under
L1/<group>/. L1/<group>/group.yamlis the canonical membership and manager file.L1/<group>/mod/is that group's customware module root.
Do not write group membership into arbitrary files. group.yaml is the contract.
Special Groups
_allis the implicit everyone group.- Do not create or rely on
L1/_all/group.yamlfor membership._allmembership is universal, not file-driven. _adminis the admin group.- Adding a user or included group to
_adminmakes those users admins.
Canonical group.yaml Fields
included_usersincluded_groupsmanaging_usersmanaging_groups
Meaning:
included_users: direct members of the groupincluded_groups: groups whose members also become members of this groupmanaging_users: users who may write this group'sL1/<group>/treemanaging_groups: groups whose members may write this group'sL1/<group>/tree
Manager inheritance is separate from membership inheritance. Do not treat included_* as manager fields or vice versa.
Create A Group
Runtime-created groups belong in L1, not L0.
jsconst groupId = "team-red"; return await space.api.fileWrite({ files: [ { path: `L1/${groupId}/` }, { path: `L1/${groupId}/mod/` }, { path: `L1/${groupId}/group.yaml`, content: space.utils.yaml.stringify({ included_groups: [], included_users: [], managing_groups: [], managing_users: [] }) } ] });
Update Membership Or Managers
Read, parse, normalize, then write group.yaml.
jsconst path = "L1/team-red/group.yaml"; const current = await space.api.fileRead(path); const config = space.utils.yaml.parse(current.content || ""); config.included_users = [...new Set([...(config.included_users || []), "alice"])].sort(); config.managing_users = [...new Set([...(config.managing_users || []), "alice"])].sort(); return await space.api.fileWrite(path, space.utils.yaml.stringify(config));
Use the same pattern for included_groups and managing_groups.
Grant Or Remove Admin Access
The canonical way to grant admin access is to edit L1/_admin/group.yaml:
- add usernames to
included_users - or add groups to
included_groups
Example:
jsconst path = "L1/_admin/group.yaml"; const current = await space.api.fileRead(path); const config = space.utils.yaml.parse(current.content || ""); config.included_users = [...new Set([...(config.included_users || []), "alice"])].sort(); return await space.api.fileWrite(path, space.utils.yaml.stringify(config));
Mental Model
- membership answers "which users belong to this group?"
- manager lists answer "which users may write this group's L1 tree?"
_adminmembership is stronger than ordinary group management because admins may write anyL1/*andL2/*_allis readable by everyone, but it is not the place to store membership rules
CLI Reference
Backend equivalents exist for operators outside the browser:
node space group create <group-id>node space group add <group-id> <user|group> <id> [--manager]node space group remove <group-id> <user|group> <id> [--manager]
From the overlay agent, prefer logical app-file edits through space.api.

