2026-07-23 20:36:37 +00:00
|
|
|
# Console — operational setup (server state, not in git)
|
|
|
|
|
|
|
|
|
|
Records the OS-level setup the admin console depends on. Reproduce this on any
|
|
|
|
|
new server; none of it lives in the repo.
|
|
|
|
|
|
|
|
|
|
## Agent runtime
|
|
|
|
|
- **OS user** `carlos-arias-agent` — system user, `/usr/sbin/nologin`, **no sudo**.
|
|
|
|
|
The headless agent runs as this user. Never as root.
|
|
|
|
|
- **HOME** `/var/lib/carlos-arias-agent` (0700). Contains `.claude.json` with
|
|
|
|
|
`hasTrustDialogAccepted: true` for the repo path (headless can't click the
|
|
|
|
|
trust dialog).
|
|
|
|
|
- **Claude binary** relocated to `/usr/local/bin/claude` (self-contained 257M
|
|
|
|
|
ELF). `/root` is `0750`, so the agent could not reach root's install.
|
|
|
|
|
- **Token** in `agents/.env` → `CLAUDE_CODE_OAUTH_TOKEN` (git-ignored, 0600).
|
|
|
|
|
A `claude setup-token` value (`sk-ant-oat01-…`). Rotate it — it passed through
|
|
|
|
|
a chat transcript during setup.
|
|
|
|
|
|
|
|
|
|
## Permissions model (no chown-to-www needed)
|
|
|
|
|
- Shared group **`caweb`**; members: `carlos-arias-agent` + `www`.
|
|
|
|
|
- `app/`, `brand/`, `api/db`, `api/cli`, `agents/` → group `caweb`, `g+rwX`,
|
|
|
|
|
setgid on dirs (new files inherit the group).
|
|
|
|
|
- `public/` and `public-preview/` → group `caweb`, `g+rwX`, setgid, world-read.
|
|
|
|
|
nginx (`www`) only needs **read** to serve, so the agent can own build output
|
|
|
|
|
and nginx still serves it — no privileged chown step.
|
|
|
|
|
|
|
|
|
|
## Build model
|
|
|
|
|
- Isolated preview: `PREVIEW_OUT=../public-preview/<jobId>`
|
|
|
|
|
`PREVIEW_BASE=/_preview/<jobId>` then `cd app && npm run build`
|
|
|
|
|
(supported natively by `app/astro.config.mjs`).
|
|
|
|
|
- Publish: normal build to `public/`, then `git commit` (rollback point).
|
|
|
|
|
|
|
|
|
|
## Verified working (2026-07-23)
|
|
|
|
|
Confined agent, as `carlos-arias-agent` with the token: reads the repo, writes
|
|
|
|
|
source, runs a 24-page isolated preview build (~7.5s), output servable by nginx.
|
|
|
|
|
Full edit→preview→serve loop proven end to end.
|
|
|
|
|
|
|
|
|
|
## Still to build (Phase 1 remainder)
|
|
|
|
|
- Runner service `agents/console/server.mjs` (Node, binds `127.0.0.1:3011`):
|
|
|
|
|
`run` / `preview` / `publish` / `discard` / `ping` / `auth` / `logout`.
|
|
|
|
|
- nginx: `/devconsole/*` + `/admin/*` → `auth_request` against a PHP admin-session
|
|
|
|
|
check → proxy to `127.0.0.1:3011`. Runner never exposed directly.
|
|
|
|
|
- Wire `DevConsole.astro` to the runner.
|
|
|
|
|
- systemd unit to keep the runner alive.
|
2026-07-23 22:55:32 +00:00
|
|
|
|
|
|
|
|
## Build ownership (IMPORTANT)
|
|
|
|
|
- `app/` and `public/` are owned by **carlos-arias-agent:caweb**. The agent runs
|
|
|
|
|
all builds and must own its output to overwrite it.
|
|
|
|
|
- **Never run `npm run build` as root** — it creates root-owned files the agent
|
|
|
|
|
then can't overwrite (EPERM in vite prepare-out-dir). If it happens, fix with:
|
|
|
|
|
`chown -R carlos-arias-agent:caweb app public`.
|
|
|
|
|
- Rebuild via the runner (`POST /devconsole/rebuild`) or
|
|
|
|
|
`sudo -u carlos-arias-agent env HOME=/var/lib/carlos-arias-agent … npm run build`.
|
|
|
|
|
- www serves `public/` via the shared `caweb` group — no chown-to-www needed.
|
|
|
|
|
|
|
|
|
|
## Phase 2/3 delivered
|
|
|
|
|
- Media upload: `POST /api/media/upload` (GD/ffmpeg optimise → app/public/media).
|
|
|
|
|
- Projects admin: `/admin/projects` (list) + `/admin/projects/edit?slug=` (gallery
|
|
|
|
|
upload/replace + Instagram URL). Saves to cja_projects, then rebuilds.
|
|
|
|
|
- `POST /devconsole/rebuild` regenerates the live site after structured edits.
|