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

9.9 KiB
Raw Blame History

name, description, metadata
name description metadata
agenthub-multi-user-goal 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)
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.