Six fixes addressing operational correctness on a real Debian host:
1. Ownership after git operations: chown -R zopu:zopu on the checkout
after clone/update/rollback before running bun install/build as the
service user. .env kept at 0600 with explicit chmod after each
operation.
2. sudo replaced with runuser: minimal Debian does not include sudo.
runuser is part of util-linux (essential) and always available.
All three scripts (bootstrap, update, rollback) now use runuser -u.
3. cron.d entry fixed: /etc/cron.d format requires a username field.
Added ${SERVICE_USER} between the time fields and the command path.
4. Firewall: added explicit `ufw allow in on tailscale0` rule so the
deny-incoming default does not block Tailscale private-overlay
reachability. Removed inaccurate claim that direct private IP works
by default; documented that an explicit per-interface rule is needed.
5. SupplementaryGroups=docker added to zopu-agent.service: the Orb
sandbox runtime lives in the agent process, not just the daemon.
6. zopu-health.service: added Environment=ENV_FILE=__INSTALL_DIR__/.env
so health-check.sh sources the correct .env at custom install paths.
Verified Flue build output: bun run build:agents produces
packages/agents/dist/server.mjs (confirmed by running the build).
Agent unit ExecStart path is correct.
Validated: bash -n on all 6 shell scripts; mocked health-check smoke
against live RivetKit engine on port 6420; systemd unit structural
checks. No JS/TS/agent files changed.
Lane D deliverable: reproducible execution-plane deployment on a fresh
Debian dedicated server (~12 cores, 40 GB RAM, single-node).
Artifacts:
- bootstrap.sh: Docker Engine, Bun, repo clone, build, systemd install,
firewall (deny-by-default), optional Tailscale, disk monitor cron
- .env.template: all 8 environment groups documented (Convex, Gitea,
model gateway, AgentOS/RivetKit, Zopu agent, daemon, Docker sandbox,
service auth)
- systemd units: zopu-daemon, zopu-agent (both Restart=always),
zopu-health timer (60s), zopu-docker-cleanup timer (daily)
- scripts: health-check, update, rollback, docker-cleanup, disk-monitor
- Caddyfile: optional reverse proxy (documentation-only by default)
- README.md: full runbook with start/stop/log/update/rollback/cleanup
procedures, topology documentation, and boundary notes
Verified topology (from installed RivetKit source):
- registry.start() boots an in-process RivetKit engine (envoy mode) with
a native Rust sidecar at http://localhost:6420 (DEFAULT_ENDPOINT in
chunk-YDUQHING.js line 4751). createClient() connects back to it.
- No separate Rivet Engine process required for single-node operation.
- Linux x64 sidecar packages (@rivet-dev/agentos-sidecar-linux-x64-gnu)
are available as optional dependencies.
Docker / Orb boundary:
- Docker Engine installed and zopu user in docker group.
- No Docker-backed sandbox code wired; Orb lane contract not yet landed.
- Volume pruning omitted from docker-cleanup.sh to protect durable data.
Validated: bash -n on all 6 shell scripts; mocked health-check smoke
(nc-based TCP probes, mocked systemctl/docker); systemd unit structural
checks. No JS/TS/agent files changed.
These were accidentally committed by git add -A picking up stash-pop
leftovers. docs/ is the canonical location; the root copies were stale
pre-rebrand duplicates.
- Fix all Ultracite lint errors on changed source files (0 remaining)
- Remove project.test.ts and use-personal-organization.test.ts (to be
rewritten when implementation stabilizes)
- Replace .at(-1) with index access for backend tsconfig ES target compat
- Rename generator functions to avoid no-shadow conflicts
- Refactor nested ternaries into helper functions
- Fix unused imports
Auth:
- Add useWebAuth hook as the single web-facing auth interface with four
states (loading/unauthenticated/authenticated/inconsistent)
- Normalize getCurrentUser to return {id: tokenIdentifier, name, email}
- Rename requireOwnerId to requireAuthUserId across all backend callers
- Set expectAuth:true on ConvexReactClient singleton
- Migrate _app, _auth, user-menu, use-personal-organization to useWebAuth
- Remove unused @code/auth/server export (zero callers confirmed)
Primitives:
- Add packages/primitives/src/project.ts with Effect v4 Project domain:
URL normalization, six canonical context kinds, strict remote decoding,
context write decisioning with revision tracking, and no-op detection
- Define PublicGit and ProjectStore replaceable ports
- Define ProjectApplication service orchestrating domain+ports with
deterministic error mapping
- Add comprehensive test suite (28 tests) with in-memory store and fake
PublicGit covering normalization, seeds, idempotency, tenant isolation,
last-write-wins, and typed error mapping