Thank you for helping keep the Code-as-Action paradigm open. This document
defines the minimal governance rules for multi-person contribution: branch
naming, the PR checklist, review policy, release policy, and the offline-test
policy. The technical conventions live in CLAUDE.md /
AGENTS.md and are binding for all contributors, human or agent.
Community participation is also governed by
CODE_OF_CONDUCT.md; suspected vulnerabilities follow
the private process in SECURITY.md.
main is always green and always releasable. Every commit on main
must pass the full offline test suite and pre-commit. Never merge a red PR.v0.2.0). Once a tag is
published it is never moved or rewritten; fixes go into a new tag.science-dev, front-backend-dev, ...) — they drift.
A temporary next integration branch is allowed only with a named owner,
explicit merge criteria, and a deletion date.try/except ImportError at every in-tree use site.# vX.Y.Z comments through the GitHub API with the job's
own read-only GITHUB_TOKEN; nothing else in ci.yml is networked, and
no job receives a repository secret.docs/TODO.md, not in a comment.
Anything this repository has decided to do and has not done — especially
when the blocker is outside the codebase, like a registry account or a
machine — belongs there with a "done when" line. A loose end recorded only
in a code comment or a merged PR description is a loose end nobody will find
again. Planned work with a status still lives in
docs/next-version-progress.md.Harness changes must establish and preserve these project invariants. Until a target contract lands, an interim change must not weaken the portions already satisfied or claim that a known gap is enforced:
system_recovery, calls no taped host.* method, and is not published as an
agent action.QUERY_DENYLIST.deny, rules_only, or allow); viewer presence is an answer channel,
never authorization._m_* method has an explicit capability specification;
unknown methods fail closed.| Prefix | Use for |
|---|---|
feat/<name> |
New features (runtime, platform, compute, ...) |
fix/<name> |
Bug fixes |
docs/<name> |
Documentation-only changes |
test/<name> |
Tests, contract coverage, fixtures |
refactor/<name> |
Refactors with no behavior change |
chore/<name> |
Tooling, CI, maintenance |
ui/<name> |
Web UI / frontend |
harness/<name> |
Test harness, evals, fakes, golden traces |
science/<name> |
Skills, science recipes, envs |
release/<name> |
Release preparation |
hotfix/<name> |
Urgent fixes on top of a release |
External PRs should target main (or a specific, announced next branch
during a coordinated integration window — never anything else).
Branch names are enforced by the branch-name CI job on every PR:
^(main|next|(feat|fix|docs|test|refactor|chore|ui|harness|science|release|hotfix)/[a-z0-9][a-z0-9._-]{1,80})$
(lowercase, 2–81 chars after the slash; Dependabot branches are exempt).
Run locally and make sure everything is green:
uv run pytest # full offline suite — no network, no keys
uv run mypy # strict agent/Host + orchestration contracts
uv run pre-commit run --all-files # black · isort · ruff · mypy · hygiene
The default test suite is offline by design: tests/conftest.py redirects
~/.openai4s to a tmp dir and configures a fake LLM provider. Do not add tests
that require live LLM calls, network access, GPUs, SSH hosts, Docker, lab
hardware, or real API keys to the default suite. Such tests must carry one of
the opt-in pytest markers registered in pyproject.toml (external,
network, live_llm, gpu, ssh, lab, docker, browser) — the default
uv run pytest run and PR CI deselect them automatically, and
--strict-markers rejects unregistered markers. Opt in explicitly with e.g.
uv run pytest -m gpu.
Every PR description must confirm (the template in
.github/pull_request_template.md asks
for each of these):
uv run pytest with no network and no secrets.uv run pre-commit run --all-files.try/except ImportError.openai4s/server/gateway.py,
openai4s/host_dispatch.py, openai4s/store.py,
openai4s/kernel/worker.py,
openai4s/kernel/manager.py — were edited surgically, never wholesale
rewritten. New workbench UI goes in frontend/, not legacy app.js;
rebuild and commit openai4s/server/webui/dist/ with the source.openai4s/server/webui/vendor/ and tests/fixtures/ were not reformatted.git ls-files --deleted is clean or explained).README.md changed in a translated section, README_zh.md was updated
to match (and vice versa)..github/CODEOWNERS) before merge.openai4s/security/,
openai4s/permissions.py, openai4s/egress.py, openai4s/store.py,
openai4s/host_dispatch.py, openai4s_compute_provider/) additionally
require review by a security-focused owner and synthetic-secret tests where
applicable.tests/test_kernel.py /
tests/test_agent.py / tests/test_gateway.py.main,
they do not push fixups onto contributor branches without agreement.Review is a first-class contribution and does not require repository write access. We especially welcome recurring reviewers in four areas:
Start by reproducing the reported behavior and leaving one evidence-backed, read-only review on a small PR. State the invariant you checked, the command or browser flow you ran, and any path you did not assess. After several substantive reviews in one area, ask a maintainer to list you as a recurring reviewer in the relevant issue/PR templates. CODEOWNERS membership is a later trust decision: it requires sustained review activity, familiarity with the path's threat and compatibility boundaries, and repository write access. It is never granted only to make a branch-protection check pass.
Maintainers should route review rather than defaulting every change to the lead: request the narrowest relevant area reviewer first, keep security ownership separate for sensitive paths, and record an unowned area as a contributor need instead of silently weakening the review rule.
main only, as annotated tags vMAJOR.MINOR.PATCH.uv run pytest, green
uv run pre-commit run --all-files, green source/artifact/install gates
described in docs/release-validation.md, and
docs that match behavior..github/workflows/release.yml,
dispatched by a maintainer with publish=true against a non-prerelease
draft release of the annotated tag. The workflow stages the assets, then
publishes to PyPI, and only then makes the release public. Never publish the
GitHub Release by hand: a public release can no longer be staged, and
pypi_only is a recovery mode that attaches nothing. The protected pypi
environment and PyPI Trusted Publisher must match that workflow; long-lived
upload tokens are not accepted. The step-by-step procedure is in
docs/release-validation.md.openai4s_compute_provider import paths during
the worker-runtime transition) are only dropped with a deprecation note in
the release notes at least one minor release in advance.Some governance pieces cannot be expressed in-repo and must be enabled in GitHub settings by an admin:
main: require PR review, require status checks,
forbid force pushes and deletions..github/workflows/ci.yml)
as a required status check..github/CODEOWNERS usernames current (owners need write access) and
enable "Require review from Code Owners".pypi and ghcr environments with required reviewers, and
restrict their deployment refs to main and v* tags. The release docs
treat both as prerequisites for publishing.refs/tags/v* that restricts tag creation and blocks
update and deletion, so a release tag stays immutable.