openvibers/openvibe.codes AGENTS.md
AGENTS.md
AGENTS.md — OpenVibe.Codes
Project overview
The open coding-agent harness: one place to send a coding task to the agent that fits it (by what the
task needs first, then cost), hand it over when an agent gets stuck, and keep the run in one place.
The same package runs on a person's own machine with their CLIs and keys; the site is the front door,
the router and the record. Node.js/Express + the harness/ package, PostgreSQL (ov_codes),
CommonJS, no build step.
- Service id
codes, port4900, originhttps://openvibe.codes, unitopenvibe-codes.service,
release root/opt/openvibe.codes; live on openvibe-ovh. - Design: plan T16 and [ADR-050](docs/adr/050-codes-harness-fabric.md). The developer console that
used to live here moved to OpenVibe.Services on 2026-10-08; every one of its addresses here is
a permanent redirect there. package.jsonmainis [harness/index.js](harness/index.js) — the installable harness — while
npm startruns [server/index.js](server/index.js), the site.
What it owns
- The harness catalog and routing policy over it; placement itself is
openvibe-sdk/placement. - The harness package ([harness/](harness/), [bin/](bin/)): adapters for Claude Code, Codex, OpenCode,
Command Code, Aider, the DeepSeek API and self-hosted models; the shared event format, hand-offs
and the local run store. - The site's records:
run_tasks(tasks started on the site or API),codes_session_lines,
attempts/hand-offs, inbound Run events and thecodes.task.*outbox. - Knowledge (
codes_knowledge), skills/Rules/MCP/commands/hooks with immutable versions
(codes_skills,codes_skill_versions), sharing, the task API/SSE stream and the agent catalog. - Pages:
/,/start,/run,/run/tasks/:id,/knowledge,/skills,/harnesses,/improve,
/policy*,/updates, and the machine endpoints.
Not owned: the sandboxes/browsers (OpenVibe.Run), the machine's Link plugin (Link), the OpenVibe Git
host (git.openvibe.codes, repo OpenVibe-Git), the AI model runs (openvibe.ai, called through the
catalog), identity/grants (Network/Services), and the console that moved to Services.
Who calls it, and whom it calls
- Callers: people in the browser; services with a Network service token audience
openvibe.codesand
codes.task.start|read|cancel(OpenVibe.Actor is the main one), usingX-OV-Subject(and
X-OV-Project) to act for a person; the CLIopenvibe-codes taskwith the person's own token. - Depends on: Network (SSO client
codes, PKCE, JWKS); AI (ai.openvibe.services— the
model catalog and completion); Run (server/domain/run-client.js— jobs in classcode,
artifact[email protected],trust: user-owned, placed only on the person's machines);
Link (openvibe-codes jobin the machine's job sandbox); Network projects for delegation;
Git (git.openvibe.codes— branch push and pull request with Codes' service token acting for
the person); PostgreSQL and Valkey; Events for the outbox.
Repository map
- Site entry: [server/index.js](server/index.js) —
createApp(), listen, graceful stop. - App: [server/app.js](server/app.js) — helmet/CSP,
/internal/events,
/internal/sandbox-workers,/auth,/shared,/api/v1(agent, task, knowledge, skills and
resource routers), pages, moved-address redirects, machine endpoints. - Harness entry: [harness/index.js](harness/index.js) —
createHarness({ env, fetch, store }),
agents(),route(),run()and the event stream; [harness/job.js](harness/job.js) is the job the
Link runs. - Domain: [server/domain/](server/domain/) —
run-tasks.js,attempts.js,harnesses.js,
harness-placement.js,knowledge.js,skills.js,run-client.js,github.js,redact.js. - HTTP: [server/http/](server/http/) —
pages.js,api.js,tasks-api.js,run.js,
knowledge.js,skills-pages.js,moved.js,discovery.js,openapi.js. - Catalog: [server/data/harness-offers.json](server/data/harness-offers.json) (validated at boot).
- Browser: [public/js/run.js](public/js/run.js),
composer.js,chat.js,c4.js,copy.js,
setup.js; CSS in [public/css/](public/css/). - Sandbox: [sandbox/](sandbox/) (bwrap/seccomp/egress, worker/supervisor),
[deploy/sandbox/](deploy/sandbox/). - Deploy: [deploy/systemd/openvibe-codes.service](deploy/systemd/openvibe-codes.service),
[deploy/nginx/openvibe.codes.conf](deploy/nginx/openvibe.codes.conf).
Commands
npm ci
npm run dev # NODE_ENV=development node server/index.js
npm start # node server/index.js, http://127.0.0.1:4900
npm test # test/run.js, temp PGlite, mock Network/Events/Media
npm run test:pg # same suite on PostgreSQL (CODES_TEST_STORE=pg)
npm test -- schedule # filter by file name; --strict makes a skip fail
ov test # the harness's sharded run of what the change reaches
The harness is also run from a machine:
npm install -g <this repo tarball>
openvibe-codes agents # what this machine can run, and why not the rest
openvibe-codes run "…" # routed, handed off on failure, kept
Database and migrations
PostgreSQL database ov_codes on the host's data role (ADR-035); PGlite in development/tests.
Async through openvibe-sdk/db; migrations migrations/NNNN_*.sql applied at boot with the owner
connection (DATABASE_DIRECT_URL). Never edit an applied migration. Migration 0002 dropped the old
console tables (rows were copied into ov_services): a rollback to a release before it finds no
console tables, so roll forward or restore ov_codes from the pre-deploy backup. Skills are
versioned: every save is an immutable version and a rollback copies an old version into a new one —
never UPDATE a version body.
Auth and task ownership
- The site signs people in with Network SSO (OAuth client
codes, PKCE S256); session tokens are
HttpOnly cookies. A FedCM assertion, an app token or a service token is never a session. - The task API accepts either the person's own Network access token (they see every task they own,
whoever started it) or a first-party service token with the route's capability plus
X-OV-Subject; a service reads/cancels only the tasks it started for that person (otherwise 404). idempotency_keymakes a retry answer the first task (200,created: false).- Per-person budgets: starts and cancels 6/minute, 60/hour.
permissionisreview(read-only),
edit(default) orfull. - Codes never sends or accepts a shared loopback key (tested by grep and at runtime).
Frontend loading model
Everything on the site is server-rendered and usable without JavaScript; small no-build scripts
under [public/js/](public/js/) enhance the run view, composer, chat and C4 pages. There is no SPA,
bundler or transpiler. openvibe-shared supplies the Frame, the session view
(openvibe-shared/agent-session.js) and /shared/* from the pinned node_modules. CSP is in
[server/app.js](server/app.js); crawl files use openvibe-shared/seo and IndexNow on deploy.
Deploy
sudo ovhost deploy codes (git-checkout: fetch, fast-forward /opt/openvibe.codes, install on a
lockfile change, restart, wait for /api/ready). Unit openvibe-codes.service on 127.0.0.1:4900,
env /etc/openvibe/codes.env; vhost
[deploy/nginx/openvibe.codes.conf](deploy/nginx/openvibe.codes.conf). Rollback
sudo ovhost rollback codes --to <sha> — mind migration 0002 above. The sandbox worker is a separate
unit/service installed from [deploy/sandbox/install.sh](deploy/sandbox/install.sh).
Tests
npm test runs each test/*.test.js in its own process through openvibe-shared/test-runner, with
PGlite and in-process Network/Events/Media mocks. It covers the harness adapters and hand-offs,
routing/catalog, the task API and attempts/SSE, knowledge and skills, redaction, the moved redirects,
the pages/llms/openapi, sandbox rules and the contracts. ov test runs the same.
Conventions
- CommonJS, 4-space indent, single quotes, semicolons; domain logic in
server/domain/, HTTP in
server/http/, harness inharness/; injectable config/db/clock/fetch/log. - The harness is standalone: it must not need OpenVibe to run, and nothing about a local run goes
through OpenVibe unless the person asks. - Errors are RFC 9457 problem+json with stable codes (
harness.invalid,harness.task_unknown,
codes.no_project); never leak a path, a key or a request body. - IDs and capability names come from
openvibe-contracts; bump the pin before using a new one.
Pitfalls
- Never push the branch a task started from. A job may push a new branch (never the base) and open
a pull request only when asked and the machine holdsGITHUB_TOKEN. - The API loop stays in the working directory, never reads
.env, never writes under.git;
the permission levels (review/edit/full) are enforced by the adapters, not by prompt text. /runtasks run on the person's own machine, not OpenVibe's. A task with no/runproject is
409 codes.no_project; do not "fix" it by placing work anywhere else.- Knowledge is private by default and redacted before storage; a shared row goes through the
share gate, never a raw link. - Skills are immutable versions; a rollback is a new version.
- Moved addresses are 301 for GET/HEAD and 308 for anything else, preserving path, query, method
and body — do not reintroduce the console. /metricsis loopback only; readiness is truthful (database + catalog required).- A service may act only for the person it names and only on the tasks it started.
Documentation
- [README.md](README.md) — every surface, the harness, API, configuration and deploy.
- [docs/adr/050-codes-harness-fabric.md](docs/adr/050-codes-harness-fabric.md) — the boundaries.
- [docs/harness-runtime.md](docs/harness-runtime.md), [docs/cli.md](docs/cli.md),
[docs/checkpoints.md](docs/checkpoints.md), [docs/agent-runs.md](docs/agent-runs.md). - [docs/model-plans.md](docs/model-plans.md), [docs/g3-local-clone.md](docs/g3-local-clone.md),
[docs/governance/](docs/governance/), [CONTRIBUTING.md](CONTRIBUTING.md).