|
| 1 | +# Contributing to Arcp |
| 2 | + |
| 3 | +Thanks for your interest in improving the F# 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 F#: |
| 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 (draft)](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 F# 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 .NET 10 (`net10.0`). The required SDK version is pinned in |
| 62 | +`global.json` (`10.0.203`, `rollForward: latestFeature`) — install a matching |
| 63 | +.NET SDK from [dot.net](https://dotnet.microsoft.com/download) and the .NET CLI |
| 64 | +will respect it automatically. NuGet is the package manager; all package |
| 65 | +versions are pinned centrally in `Directory.Packages.props`. Clone, restore |
| 66 | +local tools (Fantomas), then restore project dependencies: |
| 67 | + |
| 68 | +```sh |
| 69 | +git clone https://github.com/agentruntimecontrolprotocol/fsharp-sdk.git |
| 70 | +cd fsharp-sdk |
| 71 | +dotnet tool restore |
| 72 | +dotnet restore ARCP.slnx |
| 73 | +dotnet build ARCP.slnx --configuration Release |
| 74 | +``` |
| 75 | + |
| 76 | +## Tests and conformance |
| 77 | + |
| 78 | +Two layers must pass before a PR merges: |
| 79 | + |
| 80 | +- **Unit tests** — this SDK's own suite: |
| 81 | + |
| 82 | + ```sh |
| 83 | + dotnet test tests/Arcp.UnitTests/Arcp.UnitTests.fsproj |
| 84 | + ``` |
| 85 | + |
| 86 | +- **Conformance** — the SDK's behavior against the reference runtime. New |
| 87 | + protocol-facing code (session negotiation, event sequencing, lease handling, |
| 88 | + error mapping) needs a test that exercises the real exchange, not a mock that |
| 89 | + assumes the answer. The integration suite under |
| 90 | + `tests/Arcp.IntegrationTests` runs the F# client against the in-process |
| 91 | + `Arcp.Runtime` reference implementation; run it with |
| 92 | + `dotnet test tests/Arcp.IntegrationTests/Arcp.IntegrationTests.fsproj`. To |
| 93 | + point it at an out-of-process runtime, set the `ARCP_RUNTIME_URL` environment |
| 94 | + variable to its WebSocket endpoint before invoking the suite. |
| 95 | + |
| 96 | +CI runs both on every PR. A PR that changes which feature flags the SDK |
| 97 | +negotiates must also update the README feature matrix in the same change. |
| 98 | + |
| 99 | +## Coding standards |
| 100 | + |
| 101 | +Formatting is enforced by [Fantomas](https://fsprojects.github.io/fantomas/) |
| 102 | +(restored as a local tool); the compiler runs with |
| 103 | +`TreatWarningsAsErrors=true` plus an explicit `WarningsAsErrors` list |
| 104 | +(`FS0025;FS0026;FS0040;FS0064`) so warnings are part of the build gate. Run |
| 105 | +the same commands CI runs: |
| 106 | + |
| 107 | +```sh |
| 108 | +dotnet tool restore |
| 109 | +dotnet fantomas --check src tests samples |
| 110 | +dotnet build ARCP.slnx --configuration Release |
| 111 | +``` |
| 112 | + |
| 113 | +Match the surrounding code. Public API changes need doc comments and an entry in |
| 114 | +the changelog. Prefer clarity over cleverness in a library others build on. |
| 115 | + |
| 116 | +## Commit and pull-request conventions |
| 117 | + |
| 118 | +- Write focused commits with present-tense, imperative subjects |
| 119 | + (`add result_chunk reassembly`, not `added` / `adds`). |
| 120 | +- Reference the issue a PR closes (`Closes #123`). |
| 121 | +- Keep the PR description honest about scope and any spec sections touched. |
| 122 | +- Rebase on the default branch and ensure CI is green before requesting review. |
| 123 | +- Sign off your commits to certify the [Developer Certificate of Origin](https://developercertificate.org/): |
| 124 | + |
| 125 | + ```sh |
| 126 | + git commit -s -m "your message" |
| 127 | + ``` |
| 128 | + |
| 129 | +## Releases |
| 130 | + |
| 131 | +Releases are cut by maintainers. Pushing a `v*` tag (for example `v1.1.0`) to |
| 132 | +the default branch triggers the `publish` GitHub Actions workflow, which packs |
| 133 | +`Arcp` and `Arcp.Cli` and pushes the resulting `.nupkg`/`.snupkg` artifacts to |
| 134 | +[nuget.org](https://www.nuget.org/packages/Arcp). The SDK is versioned with |
| 135 | +semantic versioning independently of the protocol version it speaks; a protocol |
| 136 | +version bump is noted in the changelog when the negotiated ARCP version changes. |
| 137 | + |
| 138 | +## License |
| 139 | + |
| 140 | +By contributing, you agree that your contributions are licensed under the |
| 141 | +project's [Apache-2.0](LICENSE) license. |
0 commit comments