← Về thư mục
📄 / / profiles / r-and-d / raw_evidence / OpenAI4S / .github / CONTRIBUTING.md

Contributing to OpenAI4S

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.

Ground rules

  1. 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.
  2. Release tags are frozen artifacts (e.g. v0.2.0). Once a tag is published it is never moved or rewritten; fixes go into a new tag.
  3. Feature branches are short-lived and scoped. No long-lived parallel development branches (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.
  4. The core is pure stdlib. No hard third-party import may be added to the engine, LLM client, or web server. Optional science libraries must be guarded by try/except ImportError at every in-tree use site.
  5. External PRs never receive secrets. CI for pull requests must run without API keys, repository secrets, or credentials of any kind, and must not run live LLM / GPU / SSH / lab jobs or reach the network for anything but repository metadata. The one exception is the action-pin identity job, which resolves # 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.
  6. A deferred follow-up goes in 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 invariants

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:

  1. Compaction may change only the model-view context and append its archive and boundary records; it never rewrites execution, artifact, lineage, durable event, or host-call-tape truth.
  2. Resume never replays a cell, tool, or remote job. A recovery probe is marked system_recovery, calls no taped host.* method, and is not published as an agent action.
  3. Hooks and convenience rules may only tighten permissions. A standing deny is absolute.
  4. Every executed cell produces an observation, including interruption and failure paths.
  5. Secret fields never enter durable audit/events/goldens/errors or an unauthorized child process environment.
  6. Cells execute serially within a persistent kernel namespace.
  7. Each worker has at most one in-flight RPC transaction on its protocol channel; separate workers may dispatch concurrently.
  8. Provenance failures never interrupt user code, and provenance never invents a lineage edge.
  9. Artifact versions are append-only and immutable; rollback moves the latest pointer rather than changing stored bytes.
  10. The egress fence remains read-fresh so a live policy toggle applies to the next checked call.
  11. Every new Store table is reviewed for inclusion in QUERY_DENYLIST.
  12. Noninteractive permission behavior is a typed capability decision (deny, rules_only, or allow); viewer presence is an answer channel, never authorization.
  13. Every dispatcher _m_* method has an explicit capability specification; unknown methods fail closed.
  14. Every side-effecting host action produces one canonical, redacted action and outcome shared by approval, activity, and durable audit projections.
  15. Any SDK or skill that promises approval gating has contract tests for interactive, noninteractive, and durable decision-linkage behavior.

Branch naming

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).

Before opening a PR

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.

PR checklist

Every PR description must confirm (the template in .github/pull_request_template.md asks for each of these):

Review policy

Reviewer pathway

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.

Release policy

Repository settings (maintainers)

Some governance pieces cannot be expressed in-repo and must be enabled in GitHub settings by an admin: