Skip to content

Add make add-user wizard for onboarding secondary users #349

@dcellison

Description

@dcellison

Summary

Adding a secondary user post-install currently requires several manual steps the operator must execute correctly and in order. The most recent secondary-user onboarding surfaced multiple sharp edges, most of which have since been mitigated. A wizard would centralize the remaining bookkeeping while leaving prerequisites (which need human judgement) to the operator.

Prerequisites (operator handles before running wizard)

These steps inherently require human action and stay outside the wizard's scope:

  • macOS user account exists (sysadminctl -addUser <name> or System Settings).
  • Operator has logged in once as that OS user and run claude to populate that user's ~/.claude.json with OAuth tokens.
  • Operator knows the new user's Telegram chat_id, intended role, and any per-user defaults they want to set.

Proposed flow

sudo make add-user

The wizard:

  1. Prompts for required fields: telegram_id, name, os_user, role, github (optional).
  2. Prompts for per-user defaults with sensible inherited fallbacks: workspace_base, model, agent_backend, max_budget.
  3. Prompts for optional GitHub routing: github_repos, github_notify_chat_id, pr_review, issue_triage.
  4. Validates os_user exists via pwd.getpwnam BEFORE any disk mutation (same pattern as _apply_migrate in install.py post-Per-user MEMORY.md under memory/<chat_id>/ #347).
  5. Appends the entry to users.yaml atomically.
  6. Creates DATA_DIR/memory/<chat_id>/ and DATA_DIR/history/<chat_id>/ as the service identity, then chown to the target uid/gid.
  7. Seeds MEMORY.md from the tracked MEMORY.md.example.
  8. Smoke test: writes and removes a sentinel file as the target user via sudo -H -u <os_user>, surfacing permission errors immediately rather than at first message.
  9. Reminds the operator to run sudo launchctl kickstart -k system/<service-label> (or equivalent on Linux) so the running service picks up the new entry.

Why this is needed

The current flow has these traps:

  • File mode and ownership: subprocess running under a different os_user via sudo -H -u cannot write to dirs created by the service identity. This was the root cause of issue Per-user MEMORY.md under memory/<chat_id>/ #347. Lazy bootstrap fixes it for already-known users at install time but cannot fix post-install additions, because the new dir gets created service-owned the first time the new user sends a message (see ensure_user_memory docstring).
  • Step-skipping: each manual step (yaml edit, dir creation, chown, seed, restart) has a silent failure mode that only surfaces hours later when the user finally messages the bot.
  • Validation timing: a typo in os_user or a missing OS account currently surfaces as an opaque mid-stream subprocess failure rather than a wizard prompt.

A wizard that mirrors the existing make config pattern in install._cmd_config() would eliminate these traps without introducing new infrastructure.

Non-goals

  • Not creating macOS accounts. sysadminctl needs interactive password prompts; this stays outside the wizard.
  • Not running claude OAuth login for the new user. That requires a browser session as the target user.
  • Not removing users. A separate remove-user utility could mirror this pattern later.
  • Not editing install.conf. All tunables stay in the wizard surface, per existing project rule.

Follow-up

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    architectureDesign decisions and architectural directionenhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions