put rootless docker back, behind the developer gate

Uncommented at all three sites: the call and import in provisionOsAccount, the
~/.local/dockers bind-mount directory in confineUserTree, and the DOCKER_HOST block in
the member zshrc.

Not restored unconditionally, which is how it was before. It now sits behind the same
Developer check as the Postgres role — the gate that prompted disabling it in the first
place. So rolePermitsDatabase is renamed rolePermitsDevTools: it gates two things now
and a name saying "database" while deciding whether you get containers is the kind of
comment that goes stale silently.

~/.local/dockers is created for EVERY account rather than only Developers. It is two
install calls, and confineUserTree is the function that places the layout, not the one
that knows who is a Developer — so a member promoted later finds it already correct.

Postgres role work is untouched and still in place.

Verified: transpiles.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-13 12:49:32 +00:00
co-authored by Claude Opus 5
parent d6f01862fe
commit fb0286e1a9
5 changed files with 70 additions and 75 deletions
+4 -4
View File
@@ -3,7 +3,7 @@ import { getUsers, getUserById, updateUser, deleteUser, USER_ROLES, OWNER_USER_I
import type { UserRole } from 'officerdb';
import * as errors from '@@/custom-errors';
import { deprovisionOsAccount } from '@@/os-user-deprovision';
import { dropPostgresRole, provisionPostgresRole, rolePermitsDatabase } from '@@/os-user-postgres';
import { dropPostgresRole, provisionPostgresRole, rolePermitsDevTools } from '@@/os-user-postgres';
import { lookupOsUser } from '@@/os-user';
import { DATA_PATH } from '@@/data-path';
@@ -90,7 +90,7 @@ export const updateUserRoleHandler: Handler = async function (ctx) {
// ── The database role follows the platform role ──
//
// Without this the gate in `rolePermitsDatabase` is decorative: it would decide what a Developer gets at
// Without this the gate in `rolePermitsDevTools` is decorative: it would decide what a Developer gets at
// creation and then never look again, so demoting one would leave their Postgres role, their databases
// and a working password in their ~/.zshenv. A permission that survives its own revocation is worse than
// not having gated it, because the UI then says something untrue.
@@ -98,8 +98,8 @@ export const updateUserRoleHandler: Handler = async function (ctx) {
// REVOKE BEFORE RECORDING, grant after. Dropping first means a failure aborts with the role unchanged, so
// the account still says Developer and the whole thing can be retried. Doing it the other way round would
// leave a Member holding database access with nothing in the row to indicate it.
const had = rolePermitsDatabase(existing.role);
const wants = rolePermitsDatabase(role as UserRole);
const had = rolePermitsDevTools(existing.role);
const wants = rolePermitsDevTools(role as UserRole);
if (had && !wants && existing.osUser) {
const dropped = await dropPostgresRole(existing.osUser);