openvibers/openvibe.codes Commits

AGENTS.md: the context an agent starts from (#429)

OP OpenVibers committed 1 days ago · b91b343b35 · 2 files, +169 −0

Changes

ddiff --git a/AGENTS.md b/AGENTS.md
nnew file mode 100644
iindex 0000000..f490d1a
---- /dev/null
++++ b/AGENTS.md
@@@ -0,0 +1,168 @@
++# 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`, port `4900`, origin `https://openvibe.codes`, unit `openvibe-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.json` `main` is [harness/index.js](harness/index.js) — the installable harness — while
++ `npm start` runs [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 the `codes.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.codes` and
++ `codes.task.start|read|cancel` (OpenVibe.Actor is the main one), using `X-OV-Subject` (and
++ `X-OV-Project`) to act for a person; the CLI `openvibe-codes task` with 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 class `code`,
++ artifact `[email protected]`, `trust: user-owned`, placed only on the person's machines);
++ **Link** (`openvibe-codes job` in 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
++
++```bash
++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:
++
++```bash
++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_key` makes a retry answer the first task (`200`, `created: false`).
++- Per-person budgets: starts and cancels 6/minute, 60/hour. `permission` is `review` (read-only),
++ `edit` (default) or `full`.
++- 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 in `harness/`; 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 holds `GITHUB_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.
++- **`/run` tasks run on the person's own machine**, not OpenVibe's. A task with no `/run` project 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.
++- **`/metrics` is 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).
ddiff --git a/CLAUDE.md b/CLAUDE.md
nnew file mode 100644
iindex 0000000..43c994c
---- /dev/null
++++ b/CLAUDE.md
@@@ -0,0 +1 @@