Files
AgentHub/docs/claude-memory/agenthub-multi-user-goal.md
T
nntrivi2001 9c573f1e3c docs: snapshot of the project's Claude Code memory
Decisions, environment quirks and pitfalls learned while working on AgentHub
(docs/claude-memory/, indexed by MEMORY.md). Notes holding personal account
details are left out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 15:27:35 +07:00

46 lines
9.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: agenthub-multi-user-goal
description: Multi-user AgentHub server — built as a server MODE inside AgentHub (no fork); plan in docs/plans/server-mode/ (AgentHub-Server repo deleted 2026-10-09)
metadata:
type: project
---
Goal (user, 2026-10-02): AgentHub as a shared web server — login, one folder per account on the shared disk, each user sees only their own stats/tokens/prompts; admin sees and manages all; data analysts analyse token use and prompts; a shared AI Router (key exposure is not a concern); every user can switch the shared Claude native / Codex accounts and use every installed tool without reinstalling or logging in again. Company is on Claude Enterprise, one seat per person.
The plan was first kept in a separate AgentHub-Server repo. The user deleted that repo on 2026-10-09, and its README now lives in AgentHub as docs/plans/server-mode/README.md (branch s3-followups). There is one source now: AgentHub.
**Why:** the local app is still moving fast; a fork now would mean merging every change twice.
**How to apply:** build the server features as a server MODE inside the AgentHub codebase, off by default. Deployment pieces live in AgentHub too (scripts/server/, docs/SERVER-MODE.md). Fork only from a tagged stable release. User said "từ từ" — do the local work first.
**Progress:** 2026-10-06 the user confirmed one codebase + an install-time choice (`agenthub server setup`) over a separate add-on package, and S1 was built UNCOMMITTED: `server/lib/auth.js`, `/api/auth`, `users`/`auth_sessions`, `AuthGate.tsx`, `agenthub server|users`, docs/SERVER-MODE.md. 2026-10-07 the user chose: admin signs every Claude account in, each new session auto-balanced on usage/quota/$ — built the Claude account pool (server/lib/claude-pool.js, setup-tokens via CLAUDE_CODE_OAUTH_TOKEN, `agenthub accounts`), also uncommitted; user said "commits sau". 2026-10-07 S2 ownership + S6 basics + review fixes built (server/lib/scope.js, audit.js, routes/users.js, pane tokens); checklist docs/plans/server-mode/CHECKLIST.md; still uncommitted. Left: S0 spike, S3 (Linux user per account), S4 — all need sudo on a host.
**2026-10-08 scope decided** (user's 7 asks): own workspaces/sessions/stats (S2 done) + own Linux user (S3) + own skills/plugins = admin baseline + user adds own + own AI Proxy = per-user store PLUS admin's shared proxies visible to all (no key leak) + shared tool binaries (/opt, S4) + shared Claude native pool (done) + NEW Codex multi-account pool (like claude-pool). User allowed the S0 spike with sudo ON THIS MACHINE (test users agh-test1/agh-test2; log every command for undo). Checklist: docs/plans/server-mode/CHECKLIST.md.
**2026-10-08 plan review decisions** (full plan: docs/plans/server-mode/S3-PLAN.md): hidepid=invisible mandatory; HIDE shared proxy keys via an AgentHub loopback gateway (pool OAuth tokens excluded); Codex ChatGPT accounts used CONCURRENTLY (user overrode the safe 1-pane default → P7 starts with a real-account spike; report back if codex self-refresh logs others out); members get NO managed-worktree mode and NO runtime layer (EMEMBERLANE). Read access = system unit + CAP_DAC_READ_SEARCH, but NOT NoNewPrivileges/CapabilityBoundingSet (they break sudo -u). Hooks auth = peer uid via /proc/net/tcp (verified). Code waits on branch `server-s3`; commits only on ask.
**2026-10-08 progress:** worktree `.claude/worktrees/server-s3` (branch server-s3, node_modules symlinked to main's, UNCOMMITTED). P0 (ai-tools config staff-only, member cc-config cwd scoped), P1 (personal proxies `u<id>_<slug>`), P1b (proxy key gateway /api/proxy-gw, server mode only; real claude+codex verified) DONE. Next P2 needs sudo + a decision on how far to touch this dev box (prod dashboard runs here as user unit on 4820). Single-suite runner: /tmp/agh-spike/t1.sh (REPORTER=spec).
**2026-10-08 P2 INSTALLED on this machine** (user chose full install): prod dashboard :4820 now = SYSTEM unit agenthub.service running the server-s3 WORKTREE code (env file ~/.claude/agenthub/runtime/agenthub.system.env); user unit disabled; hidepid=invisible on /proc; /etc/sudoers.d/agenthub; /etc/claude-code/managed-settings.json (member-hook); ah-admin + ah-vinnt exist. Undo: /tmp/agh-spike/UNDO.sh (step 0 = `install-system --uninstall`). A plugin update while this runs may race (old bootstrap doesn't know the system unit).
**2026-10-08 P3–P5 + P8 review fixes done & redeployed on this box** (still UNCOMMITTED on server-s3): 4-lens review found the host acting on member-owned paths (tmux client on member socket, writes into handoff, cap reads via swapped links) → fixed: all member tmux via sudo -u (+ pane-launch launch file), all home writes via write-as, fd+uid-checked reads, setpriv drops ambient cap for children. Live e2e as s3probe passed (pane, WS attach, Claude via gateway "pong", stage-hunk, partial commit, drop, symlink-swap refused). P7 spike done (free ChatGPT acct now in host ~/.codex): an OLD refresh token still refreshes after rotation → concurrent panes OK. Left: P6 (seed ~/.claude.json onboarding/trust, managed plugin baseline), P7 build, user's :4830 dev server still abandons member runs.
**2026-10-08 role rename hazard:** another session's UNCOMMITTED main-checkout work renamed role `member`→`developer` and migrated the SHARED dashboard.db (users CHECK now admin/analyst/developer). server-s3 bridges it in auth.js (`roleIn`/`roleOut`, ponytail) — before that, a developer on :4820 saw everything. At merge: take main's rename, drop the bridge. Also done 10-08: per-account first-run wizard + spotlight tour (`/api/me/prefs`, docs/plans/onboarding), P6 provision seed.
**2026-10-09 S3 code-complete and on origin/main (84e2a9f0, not released):** P4 per-member quota, P6 plugin baseline (managed-settings spike script written, NOT run), P7 Codex pool, and five review rounds F1–F49, each fix with a regression test. All of it was verified with fake sudo only. Still open:
- a live test on real accounts/sudo;
- the P6 spike;
- async tmux/copy (two ponytail ceilings);
- an Express-5 upgrade must drop the Layer.handle_request patch in server/index.js.
Work branch s3-next (worktree kept). Round-3 findings: ~/.cache/agenthub-s3/r3/.
**2026-10-09 follow-ups (branch s3-followups → released in v2.6.0):**
- plan README moved in;
- Express patch guarded to 4.x;
- P6 spike RUN on agh-test1: managed settings work from the first interactive session (onboarding must be seeded); `claude plugin list` stays [] because no user-scope record is written; details in S3-PLAN P6. Log: ~/.cache/agenthub-s3/LIVE-LOG.md;
- all of it RELEASED in v2.6.0 (fa156d6a) on 10-09; async member tmux listing and async snapshot copy included; server suite 2840/2843 (3 = port 3000 env). Remaining ceiling: a click/hasSession on a frozen member still blocks ≤3 s once per back-off.
**2026-10-12 prod box update:** the system unit still runs `.claude/worktrees/server-s3`, which had been left on a WIP commit over v2.5.12, so the dashboard's Update failed (`merge --ff-only` on a diverged branch; that old code predates the v2.6.1 `diverged_from_release` guard). Fixed by moving branch server-s3 to v2.7.1 (`reset --keep`; WIP pinned as branch `server-s3-wip-87903d47`), then `NODE_ENV=development npm run setup`, `NODE_ENV=production npm run build`, `sudo -n systemctl restart agenthub.service` (sudo -n works here). Future updates of this box should fast-forward cleanly.
**2026-10-12 live e2e as `test` (developer, pw 123456789, provisioned ah-test by the user):** scoping, WS, AI proxy, git as member, shell pane, isolation all OK. Root cause of "user's :4830 dev server abandons member runs" found and fixed in v2.7.2 (`linux-accounts.unseenMemberFolder`) — the OLD :4830 process still breaks member panes until restarted. Left to test after prod updates to 2.7.2: Claude via 9router gateway, Codex, member quota, skills in session. Open UX findings: ensure/start accept a missing folder (pane falls back to home), no mkdir for a new member, `--allow-dangerously-skip-permissions` always passed → Trust + Bypass consent prompts on first run. Auto-mode classifier blocks: sudoers log tweaks (audit tampering), `users provision` (permission grant). Leftovers: lane 49, proxy u5_e2e-probe, ~/proj in ah-test home, ~/.cache/agenthub-e2e.
**2026-10-12 v2.7.3 on prod (:4820 system unit, worktree server-s3 = 5d8fc9bb):** full member e2e as `test` PASSED — Claude + Codex via 9router gateway (pong), runs stay running, tokens recorded, home prompt box -> reply, Chat UI -> reply, no API >=400 for a developer, plugin baseline sg-all in member cache. Root causes fixed: (1) self-restart under the system unit crash-looped it (detached replacement held the port; recover = SIGTERM the orphan); (2) :4830 dev server runs in SERVER MODE (settings.env AGENTHUB_MODE=server) without CAP_DAC_READ_SEARCH -> EACCES on member 0700 tmux dir -> ended member runs; (3) cross-process stale tmux cache -> 20 s young-run grace. Known/left: trust prompt per member project (Claude doesn't inherit home trust), first-run Bypass consent (by design), 404 /api/pricing/cost for a brand-new session, developer System page shows host paths/DB size. test's workspace #49 + ~/proj kept as a demo.
**2026-10-12 v2.7.4 LOCAL (branch release-2.7.4 = c1241123, tag v2.7.4 local only, NOT pushed — push/release was classifier-blocked after the user asked to limit Gitea pushes):** prod :4820 runs it. Added: makeMemberFolder (start makes a missing folder in a member's home, as them), bypass flag only when skipDangerousModePermissionPrompt or a bypass run, developer /api/settings/info + /api/updates/status carry no paths (transcript_cache.keys leaked every user's transcript paths). Verified live: admin Users page (add analyst w/ step-up, EREAUTH, disable/enable, role, ESELF), analyst reads all/writes own, new analyst folder + first Claude session with no dialogs, load 12 viewers p95 ~95 ms 0 errors. Test accounts: testadmin (random pw in ~/.cache/agenthub-e2e/testadmin.cred), testanalyst (.cred there too), test/123456789. Live Update-button test still needs a pushed release newer than prod.