# Contributor handoff — curl/curl

> Canonical page: https://codevetter.com/unpack/curl/agent-handoff

# Contributor handoff — curl/curl

Scanned commit c362f034692e05ecb4d33edb740ba64c63a20add (2026-09-22). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

Treat this repo as two coupled codebases with one very strict style contract. Read the internals docs before the code — docs/internals/ explains the four architectural ideas (connection filters, client writers, client readers, the multi state machine) that the code assumes you already know. Style is machine-enforced: `scripts/checksrc.pl` runs in CI and by default in debug builds, and a style violation fails the build before your logic is ever reviewed. Anything user-visible needs a matching curldown doc and usually a test case, and several files are generated and must not be hand-edited. The safest edits are additive table rows; the riskiest are changes to lib/multi.c, lib/url.c, lib/sendf.c, or lib/cfilters.c, which every protocol depends on.
- Read first, in this order: docs/internals/README.md and the four core internals docs (CONNECTION-FILTERS.md, CLIENT-WRITERS.md, CLIENT-READERS.md, MID.md), then src/tool_main.c and src/tool_operate.c for the tool, then lib/easy.c and lib/multi.c for the library. — [docs/internals/README.md](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/docs/internals/README.md) [docs/internals/CONNECTION-FILTERS.md](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/docs/internals/CONNECTION-FILTERS.md) [src/tool_operate.c#L2422](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/src/tool_operate.c#L2422) [lib/multi.c#L2714](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/lib/multi.c#L2714)
- Style is non-negotiable and automated: docs/internals/CODE_STYLE.md is enforced by `scripts/checksrc.pl`, invoked via `make checksrc`, run automatically after `./configure --enable-debug`, and gated in CI by `scripts/checksrc-all.pl`. — [docs/internals/CODE_STYLE.md#L17-L28](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/docs/internals/CODE_STYLE.md#L17-L28) [docs/internals/CHECKSRC.md#L7-L50](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/docs/internals/CHECKSRC.md#L7-L50) [.github/workflows/checksrc.yml#L38-L47](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/.github/workflows/checksrc.yml#L38-L47)
- `make lint` is the full pre-push check: it runs `scripts/badwords-all`, `make checksrc` across lib/src/tests/include/examples/projects, and `scripts/spacecheck.pl`. — [Makefile.am#L194-L210](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/Makefile.am#L194-L210) [scripts/spacecheck.pl](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/scripts/spacecheck.pl) [scripts/badwords-all](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/scripts/badwords-all)
- Do not hand-edit generated files: src/tool_hugehelp.c is produced by src/mkhelp.pl from the manpage during the build, and src/tool_listhelp.c is likewise generated option-help data. — [src/Makefile.am#L123-L185](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/src/Makefile.am#L123-L185) [src/mkhelp.pl](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/src/mkhelp.pl) [src/tool_listhelp.c](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/src/tool_listhelp.c)
- Docs are written in curldown (a markdown dialect with a YAML-ish front matter carrying `Title`, `Section`, `Added-in`, `See-also`), documented in docs/CURLDOWN.md and converted by scripts/managen; the checkdocs workflow validates them. — [docs/CURLDOWN.md](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/docs/CURLDOWN.md) [docs/runtests.md#L1-L12](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/docs/runtests.md#L1-L12) [scripts/managen](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/scripts/managen) [.github/workflows/checkdocs.yml](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/.github/workflows/checkdocs.yml)
- Adding a test means creating tests/data/testNNNN in the XML-like format and adding it to the numerically-ordered `TESTCASES` list in tests/data/Makefile.am — the file is not picked up automatically. — [tests/data/Makefile.am#L24-L40](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/tests/data/Makefile.am#L24-L40) [tests/data/test1#L1-L54](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/tests/data/test1#L1-L54)
- To run tests: `make test` (quiet) from the top, or drive the harness directly with `TFLAGS` — `cd tests && ./runtests.pl 1 to 200`, keyword selection like `FTPS` or `!feat:proxy`, `-t` for torture, and `make pytest` for the HTTP/2-3 python suite. — [Makefile.am#L126-L158](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/Makefile.am#L126-L158) [tests/Makefile.am#L144-L178](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/tests/Makefile.am#L144-L178) [docs/runtests.md#L26-L50](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/docs/runtests.md#L26-L50)
- Public ABI is a hard boundary: include/curl/curlver.h carries the version macros, docs/libcurl/ABI.md states the compatibility promise, and docs/libcurl/symbols-in-versions records when every symbol appeared — new symbols must be added there. — [include/curl/curlver.h#L35-L75](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/include/curl/curlver.h#L35-L75) [docs/libcurl/ABI.md](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/docs/libcurl/ABI.md) [docs/libcurl/symbols-in-versions](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/docs/libcurl/symbols-in-versions)
- Any new code must still compile with features disabled: wrap protocol/feature-specific code in the relevant `CURL_DISABLE_*` guard as documented in docs/CURL-DISABLE.md, and use `scripts/randdisable` to sanity-check random combinations. — [docs/CURL-DISABLE.md#L9-L130](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/docs/CURL-DISABLE.md#L9-L130) [scripts/randdisable](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/scripts/randdisable) [lib/protocol.c#L46-L70](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/lib/protocol.c#L46-L70)
- Both build systems must be updated together: file lists live in lib/Makefile.inc and src/Makefile.inc for autotools and in lib/CMakeLists.txt / src/CMakeLists.txt for CMake, and configure-vs-cmake.yml exists to catch divergence. — [lib/Makefile.inc](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/lib/Makefile.inc) [src/Makefile.inc](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/src/Makefile.inc) [lib/CMakeLists.txt](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/lib/CMakeLists.txt) [.github/workflows/configure-vs-cmake.yml](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/.github/workflows/configure-vs-cmake.yml)
- Do not hand-write RELEASE-NOTES entries: it is maintained by scripts/release-notes.pl and the release flow in docs/RELEASE-PROCEDURE.md (the most recent commit on this branch is literally "RELEASE-NOTES: synced"). — [scripts/release-notes.pl](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/scripts/release-notes.pl) [RELEASE-NOTES](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/RELEASE-NOTES) [docs/RELEASE-PROCEDURE.md](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/docs/RELEASE-PROCEDURE.md)
- Never file a suspected vulnerability as a normal PR or issue: SECURITY.md and docs/VULN-DISCLOSURE-POLICY.md require private reporting through the curl disclosure process. — [SECURITY.md#L7-L18](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/SECURITY.md#L7-L18) [docs/VULN-DISCLOSURE-POLICY.md](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/docs/VULN-DISCLOSURE-POLICY.md) [docs/BUG-BOUNTY.md](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/docs/BUG-BOUNTY.md)
- Trap: the `aliases[]` table in src/tool_getparam.c must stay alphabetically sorted by long name — `findlongopt()` binary-searches it, so an out-of-order insertion silently breaks option lookup rather than failing to compile. — [src/tool_getparam.c#L75-L78](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/src/tool_getparam.c#L75-L78) [src/tool_getparam.c#L1083-L1090](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/src/tool_getparam.c#L1083-L1090)
- Trap: tool code should call the `curlx_*` wrappers (`curlx_open`, `curlx_fopen`, `curlx_stat`, `curlx_strdup`, `curlx_safefree`, `curlx_dyn_*`) rather than libc directly — the wrappers carry the Windows/VMS/unicode portability that plain libc calls lose. — [lib/curlx/win32-fopen.h](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/lib/curlx/win32-fopen.h) [src/tool_operate.c#L1146-L1160](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/src/tool_operate.c#L1146-L1160) [docs/internals/CURLX.md](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/docs/internals/CURLX.md)
- Trap: much of the interesting test machinery only exists in debug builds (`DEBUGBUILD`) — `curl_easy_perform_ev()`, `parallel_event()`, `CURL_FORBID_REUSE`, `CURL_MEMDEBUG`, `--test-duphandle` — so a change verified only against a release build has not been exercised by the full suite. — [lib/easy.c#L866-L880](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/lib/easy.c#L866-L880) [src/tool_operate.c#L1672-L1902](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/src/tool_operate.c#L1672-L1902) [src/tool_main.c#L110-L138](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/src/tool_main.c#L110-L138)
- Safe edit boundaries: adding a row to a registry (schemes, filters, writers, aliases, writeout variables) is low-risk and local; edits inside lib/multi.c's state machine, lib/url.c's connection-reuse matching, or lib/sendf.c's writer stack affect every protocol at once and need the full suite plus pytest. (inferred) — [lib/multi.c#L2714-L2890](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/lib/multi.c#L2714-L2890) [lib/url.c#L700-L910](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/lib/url.c#L700-L910) [lib/sendf.c#L331-L395](https://github.com/curl/curl/blob/c362f034692e05ecb4d33edb740ba64c63a20add/lib/sendf.c#L331-L395)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
