Outbound-only Linux/systemd AgentV for bounded diagnostics and allowlisted service recovery.
This repository owns the AgentV code, systemd packaging assets, production image, AgentV protocol contract, and agent-level docs. Central platform deployment wiring belongs in acornops-deployment.
This repository supports human and agent-assisted development. Start coding
agents from this repository root for AgentV-only work, and from the AcornOps
workspace cloned from the acornops
repository for changes that touch multiple AcornOps repositories.
Cross-repo contract documentation lives in docs/contracts/README.md. This repo's direct platform dependency is the control-plane outbound agent bridge documented there.
Machine-readable contract data lives in docs/contracts/manifest.json.
Run npm run contracts:check to mechanically verify the documented AgentV/control-plane contract shape.
Coverage is generated in CI with Vitest V8 coverage, uploaded as a workflow
artifact, and published to Codecov when CODECOV_TOKEN is configured for the
repository. Run npm run test:coverage:all locally to include transport E2E
coverage and enforce the release floors. Reports are written as text, HTML, and lcov
reports under coverage/.
Primary docs:
AGENTS.mdARCHITECTURE.mddocs/index.mddocs/DEVELOPMENT.mddocs/OPERATIONS.md- Whole-system architecture:
../docs/system-architecture.md
- Outbound-only: Initiates a secure WebSocket connection to the control plane.
- Host snapshots: Collects bounded Linux/systemd telemetry for host, filesystems, degraded services, processes, listeners, findings, and collector health. Raw logs are never included.
- MCP bridge: Serves JSON-RPC
tools/listandtools/callrequests from the platform. - Read-only by default: Eight strict tools inspect host state through fixed Linux/systemd adapters.
- Isolated writes: Optional
restart_serviceactions cross privilege only through a root-owned socket helper and exact local allowlist. - Production transport: Authenticated readiness, session generations, jittered reconnects, ping/pong deadlines, and hard inbound/outbound limits.
- Runtime: Node.js 22+
- Language: TypeScript
- Core Libraries:
ws, Zod, Vitest, and TypeScript; systemd integration uses the fixedsystemd-notifybinary - Packaging: Docker image and Linux systemd unit assets
The agent is configured with environment variables:
| Variable | Description | Default |
|---|---|---|
ACORNOPS_AGENT_PLATFORM_URL |
Control-plane HTTPS base URL. The agent appends /api/v1/agent/connect. |
Required |
ACORNOPS_AGENT_ADDITIONAL_CA_BUNDLE_FILE |
Optional readable PEM bundle added to normal public CA trust for the control-plane WebSocket. | Empty |
ACORNOPS_AGENT_ALLOW_INSECURE_TRANSPORT |
Allows http:// only for local development. Do not set in production. |
false |
ACORNOPS_TARGET_ID |
Control-plane VM target id this agent key is bound to. | Required |
ACORNOPS_AGENT_KEY |
Agent authentication token. | Required |
ACORNOPS_AGENT_TARGET_TYPE |
Target type advertised during handshake. | virtual_machine |
ACORNOPS_AGENT_SNAPSHOT_INTERVAL_MS |
Local snapshot cadence used unless the authenticated remote value is within local bounds. | 60000 |
ACORNOPS_AGENT_MAX_SNAPSHOT_BYTES |
Maximum serialized snapshot payload size. | 1048576 |
ACORNOPS_AGENT_LOG_LEVEL |
Logging level (debug, info, warn, error). |
info |
ACORNOPS_VM_OS_FAMILY |
VM operating system family. The current contract supports linux. |
linux |
ACORNOPS_VM_SERVICE_MANAGER |
VM service manager. The current contract supports systemd. |
systemd |
ACORNOPS_VM_ALLOWED_LOG_UNITS |
Comma-separated exact systemd units accepted by query_logs. |
Empty |
ACORNOPS_VM_COLLECTOR_MODE |
Collector mode: live for Linux/systemd hosts, mock for local and CI development. |
live |
ACORNOPS_AGENT_WRITE_ENABLED |
Locally permit helper-backed writes. The helper policy and remote session must also permit them. | false |
ACORNOPS_AGENT_MOCK_ACTIONS_ENABLED |
Simulate an allowlisted ssh.service restart for the Docker-only mock fixture. Requires mock collector mode and local writes; never enables production writes. |
false |
ACORNOPS_AGENT_ACTIONS_SOCKET |
Root-owned action helper socket. | /run/acornops-agentv/actions.sock |
Install dependencies:
npm installRun validation:
npm run validateRun the agent against a local control plane with mock host data:
ACORNOPS_AGENT_PLATFORM_URL=http://127.0.0.1:8081 \
ACORNOPS_AGENT_ALLOW_INSECURE_TRANSPORT=true \
ACORNOPS_TARGET_ID=your-vm-target-id \
ACORNOPS_AGENT_KEY=your-agent-key \
ACORNOPS_AGENT_TARGET_TYPE=virtual_machine \
ACORNOPS_VM_COLLECTOR_MODE=mock \
npm run devUse ACORNOPS_VM_COLLECTOR_MODE=mock for local Docker and CI. Use live on a Linux host with systemd and journald available.
Set both ACORNOPS_AGENT_WRITE_ENABLED=true and ACORNOPS_AGENT_MOCK_ACTIONS_ENABLED=true to try the run-policy-gated restart_service flow against the mock fixture's ssh.service. The default target policy requires approval; an explicit auto-run policy can allow this reviewed non-destructive action. This is a simulation, not a host restart; it preserves the fixture's active/running preconditions and returns a synthetic restart receipt.
Systemd packaging assets live in packaging/systemd:
acornops-agentv.service: hardened unprivileged main service.acornops-agentv-actions.socketand.service: disabled-by-default privileged helper.agentv.env.example: environment file template.agentv-actions.json.example: empty exact-unit helper policy.install.sh,install-worker.sh, anduninstall.sh: transactional install helpers for the service assets.acornops-agentv-install-recoverand its unit: boot recovery for interrupted cutovers.
Tagged releases also publish install-agentv.sh and its checksum. The
control plane generates a version-pinned bootstrap command that downloads the
matching archive and checksum, verifies the archive, runs install.sh, writes
the target configuration, runs the doctor, and starts the service. The
bootstrap is safe to rerun for the same version, upgrades, and explicit
credential replacement. Initial and replacement commands exchange a 15-minute
one-use enrollment token; repair and upgrade reuse the protected local
credential.
The onboarding policy is read-only by default. When an operator selects
read-write access, the enrollment carries only exact restartable systemd unit
names. The root bootstrap installs that snapshot in
/etc/acornops/agentv-actions.json and enables the privileged socket; the
copied command remains the same one-command flow. Every allowed restart
remains subject to the control-plane run permission policy; auto-run applies
only when an operator deliberately selects it there.
Runtime configuration belongs in /etc/acornops/agentv.env. Keep that file owned by root:acornops-agent with mode 0640 because it contains the agent key.
The initial bootstrap requires the host trust store to validate both artifact
and platform HTTPS endpoints. An optional
ACORNOPS_AGENT_ADDITIONAL_CA_BUNDLE_FILE runtime setting is preserved across
repair, upgrade, and credential replacement; it does not replace initial host
trust and never disables TLS verification.
Run acornops-agentv-doctor after installation. Releases live under
/opt/acornops/agentv/releases/<version> and current changes atomically, so
rollback is a symlink switch followed by a service restart.
The systemd archive bundles its production Node dependencies and uses the
target host's /usr/bin/systemd-notify for watchdog notifications. No
target-side npm install, compiler, or native addon build is required.
Node.js 22 or newer must already be installed at /usr/bin/node; the bootstrap
does not add package repositories or modify host packages.
Canonical validation:
npm run validateFocused checks:
npm run typecheck
npm run test
npm run test:coverage:all
npm run contracts:check
npm run harness:check
npm run build
npm run smoke:packageThe hosted Ubuntu 24.04 workflow additionally runs the guarded smoke:systemd gate
against real systemd, journald, procfs, socket inspection, and the privileged
helper. It covers install, doctor, allowlisted restart, idempotent replay,
upgrade, rollback, and uninstall preservation. The script intentionally refuses
to run unless both CI=true and AGENTV_SYSTEMD_SMOKE_ALLOW=true are present.