|
| 1 | +# Contributing to arcp |
| 2 | + |
| 3 | +Thanks for your interest in improving the Python SDK for ARCP. This |
| 4 | +document covers how to report issues, propose changes, and get a change merged. |
| 5 | + |
| 6 | +By participating you agree to the [Code of Conduct](CODE_OF_CONDUCT.md). |
| 7 | + |
| 8 | +## Where changes belong |
| 9 | + |
| 10 | +ARCP is two things in two places, and a change belongs to exactly one of them: |
| 11 | + |
| 12 | +- **The protocol** — the wire format, message semantics, lease rules, error |
| 13 | + taxonomy, feature flags. These live in the |
| 14 | + [specification repository](https://github.com/agentruntimecontrolprotocol/spec). |
| 15 | + If your idea changes what goes *on the wire* or what a conformant runtime must |
| 16 | + do, it is a spec change — open it there, not here. This SDK implements the |
| 17 | + spec; it does not define it. |
| 18 | +- **This SDK** — how the protocol is expressed idiomatically in Python: |
| 19 | + bugs, ergonomics, performance, missing-but-specified features, docs, tests. |
| 20 | + Those belong here. |
| 21 | + |
| 22 | +When in doubt, open an issue here and we'll redirect if it's really a protocol |
| 23 | +question. |
| 24 | + |
| 25 | +## The golden rule: conform, don't extend |
| 26 | + |
| 27 | +A change to this SDK must keep it a faithful client of |
| 28 | +[ARCP v1.1](https://github.com/agentruntimecontrolprotocol/spec/blob/main/docs/draft-arcp-1.1.md). |
| 29 | +Concretely: |
| 30 | + |
| 31 | +- **Don't invent wire behavior.** No envelope fields, event kinds, error codes, |
| 32 | + or feature flags that the spec doesn't define. If you need one, it's a spec |
| 33 | + proposal first. |
| 34 | +- **Negotiate honestly.** Only advertise a feature flag in `session.hello` once |
| 35 | + the SDK actually implements it. The feature matrix in the README must match |
| 36 | + what the code negotiates — a row marked `Supported` is a promise. |
| 37 | +- **Respect the semantics.** Sequence numbers stay gap-free and monotonic; |
| 38 | + `LEASE_EXPIRED` and `BUDGET_EXHAUSTED` stay non-retryable; the effective |
| 39 | + feature set is the intersection of client and runtime advertisements. Tests |
| 40 | + must not paper over a semantic the spec requires. |
| 41 | +- **Stay layered.** This SDK controls runtimes. It does not expose tools (that's |
| 42 | + MCP) or export telemetry (that's OpenTelemetry). PRs that blur those layers |
| 43 | + will be asked to move the logic out. |
| 44 | + |
| 45 | +## Reporting bugs |
| 46 | + |
| 47 | +Open an issue with: the SDK version and Python version, the runtime you |
| 48 | +connected to, a minimal reproduction (the smallest program that triggers it), |
| 49 | +what you expected, and what happened. A failing test is the best possible bug |
| 50 | +report. Wire-level traces (the envelopes exchanged) help enormously for protocol |
| 51 | +behavior — redact any `auth.token` or provisioned-credential `value` first. |
| 52 | + |
| 53 | +## Proposing a change |
| 54 | + |
| 55 | +For anything beyond a small fix, open an issue describing the problem before |
| 56 | +writing code, so we can agree on the approach. Small, focused PRs review faster |
| 57 | +than large ones; if a change is big, say so early and we'll help break it down. |
| 58 | + |
| 59 | +## Development setup |
| 60 | + |
| 61 | +The SDK targets Python 3.11+ and is developed with [uv](https://docs.astral.sh/uv/) |
| 62 | +as the package manager (the lockfile is `uv.lock`). Install uv, then clone and |
| 63 | +sync the project — that creates a `.venv/` with all runtime and dev dependencies |
| 64 | +pinned to the lock. |
| 65 | + |
| 66 | +```sh |
| 67 | +git clone https://github.com/agentruntimecontrolprotocol/python-sdk.git |
| 68 | +cd python-sdk |
| 69 | +uv sync --frozen --all-extras --dev |
| 70 | +``` |
| 71 | + |
| 72 | +Optionally enable the local pre-commit gates (CI is the canonical gate; this is |
| 73 | +a convenience): |
| 74 | + |
| 75 | +```sh |
| 76 | +uv run pre-commit install |
| 77 | +uv run pre-commit install --hook-type pre-push |
| 78 | +``` |
| 79 | + |
| 80 | +## Tests and conformance |
| 81 | + |
| 82 | +Two layers must pass before a PR merges: |
| 83 | + |
| 84 | +- **Unit tests** — this SDK's own suite: |
| 85 | + |
| 86 | + ```sh |
| 87 | + uv run pytest |
| 88 | + ``` |
| 89 | + |
| 90 | +- **Conformance** — the SDK's behavior against the reference runtime. New |
| 91 | + protocol-facing code (session negotiation, event sequencing, lease handling, |
| 92 | + error mapping) needs a test that exercises the real exchange, not a mock that |
| 93 | + assumes the answer. The in-tree conformance harness lives at |
| 94 | + `tests/conformance/` and runs as part of `uv run pytest`; the end-to-end |
| 95 | + suites under `tests/e2e/` drive the reference runtime over the in-process |
| 96 | + `MemoryTransport` and over `WebSocketTransport` on a loopback socket — no |
| 97 | + external server or environment variable is required. The full conformance |
| 98 | + matrix this SDK is measured against is published at |
| 99 | + [`docs/conformance.md`](docs/conformance.md). |
| 100 | + |
| 101 | +CI runs both on every PR. A PR that changes which feature flags the SDK |
| 102 | +negotiates must also update the README feature matrix in the same change. |
| 103 | + |
| 104 | +## Coding standards |
| 105 | + |
| 106 | +This repo uses Ruff for linting and formatting and Pyright for type-checking. |
| 107 | +Run them locally before pushing: |
| 108 | + |
| 109 | +```sh |
| 110 | +uv run ruff check . |
| 111 | +uv run ruff format --check . |
| 112 | +uv run pyright |
| 113 | +``` |
| 114 | + |
| 115 | +Match the surrounding code. Public API changes need doc comments and an entry in |
| 116 | +the changelog. Prefer clarity over cleverness in a library others build on. |
| 117 | + |
| 118 | +## Commit and pull-request conventions |
| 119 | + |
| 120 | +- Write focused commits with present-tense, imperative subjects |
| 121 | + (`add result_chunk reassembly`, not `added` / `adds`). |
| 122 | +- Reference the issue a PR closes (`Closes #123`). |
| 123 | +- Keep the PR description honest about scope and any spec sections touched. |
| 124 | +- Rebase on the default branch and ensure CI is green before requesting review. |
| 125 | +- Sign off your commits to certify the [Developer Certificate of Origin](https://developercertificate.org/): |
| 126 | + |
| 127 | + ```sh |
| 128 | + git commit -s -m "your message" |
| 129 | + ``` |
| 130 | + |
| 131 | +## Releases |
| 132 | + |
| 133 | +Releases are cut by maintainers. Publishing is automated: pushing a `v*` tag |
| 134 | +triggers the `publish.yml` workflow, which builds the wheel with `hatch` and |
| 135 | +uploads it to [PyPI](https://pypi.org/project/arcp/) via OIDC trusted |
| 136 | +publishing. The SDK is versioned with semantic versioning independently of the |
| 137 | +protocol version it speaks; a protocol version bump is noted in the changelog |
| 138 | +when the negotiated ARCP version changes. |
| 139 | + |
| 140 | +## License |
| 141 | + |
| 142 | +By contributing, you agree that your contributions are licensed under the |
| 143 | +project's [Apache-2.0](LICENSE) license. |
0 commit comments