Repository Conventions
This page is for contributors changing icey itself.
The architecture and module guides explain how the runtime works. The contributing guide explains workflow and release mechanics. This page covers the repository-specific rules that keep new code aligned with the existing structure.
Module Shape
Each module lives under src/<module>/.
The normal layout is:
src/<module>/
├── CMakeLists.txt
├── README.md
├── include/icy/... # public headers
├── src/ # implementation
├── tests/ # behavioural and contract coverage
├── samples/ # runnable examples
├── bench/ # focused microbenchmarks
├── perf/ # comparative or reportable performance harnesses
├── fuzz/ # fuzz targets for parser or protocol surfaces
└── apps/ # product-style binaries layered on the moduleOnly the first four are expected everywhere. The rest are added when the module actually needs them.
Use the module README as the short local map: namespace, CMake target, primary headers, directory layout, and the next docs to read. Keep that README brief and contributor-oriented.
Public API Placement
- Public headers live under
src/<module>/include/icy/.... - Implementation files live under
src/<module>/src/. - Public CMake targets use the
icey::<module>namespace. - Public package, docs, and target naming stays lowercase
icey.
Do not add new public headers outside include/icy. If a type is part of the supported API surface, it should be discoverable there.
CMake Conventions
New modules should follow the existing target pattern and be declared with icy_add_module(...).
The expectations are:
- declare module-to-module dependencies explicitly with
DEPENDS - declare third-party packages explicitly with
PACKAGES - gate optional modules on real prerequisites such as
HAVE_OPENSSL,HAVE_FFMPEG, orHAVE_LIBDATACHANNEL - expose dependencies as
PUBLIConly when the public headers require them - keep implementation-only links and include directories
PRIVATE
The repo is intentionally target-based. Avoid ad-hoc global include paths, raw compiler flag mutation, or implicit transitive dependency assumptions when a target declaration can state the contract directly.
Runtime Contracts Are Design Constraints
Most behavioural bugs in icey come from violating the runtime model, not from syntax or formatting drift.
Before changing base, net, http, av, or webrtc, keep these rules in view:
- most runtime objects are loop-affine
- receive buffers are borrowed
send()is the borrowed fast path andsendOwned()is the retained pathPacketStreamstays zero-copy until an explicit retention boundaryclose()is asynchronous
Use runtime-contracts.md as the source of truth. Do not widen contracts "just in case" by making a signal cross-thread, adding retention, or inserting queues unless the code path actually needs that broader contract.
Tests, Samples, And Performance
- Behavioural changes should come with test coverage in the owning module's
tests/directory or the top-leveltests/tree. - User-facing workflows should usually have a runnable sample or app when the feature is not obvious from unit tests alone.
- Benchmark and perf harnesses should be updated only when the changed code affects measured hot paths or published performance claims.
Tests are not an afterthought here. If a change touches lifetime, shutdown, ownership, protocol parsing, queueing, or async state flow, assume it needs a test unless there is a clear reason it does not.
Documentation Expectations
When the public surface changes, update the docs that own that surface.
That usually means some combination of:
- the module guide in
docs/modules/ - a concept page in
docs/concepts/ - a runnable recipe in
docs/recipes/ - the module README in
src/<module>/README.md - root-level docs such as
README.md,CHANGELOG.md, or release notes when the change is externally visible
Keep generated API reference concerns separate from prose docs. The prose explains the model and workflows; the generated API tab explains the exact types and signatures.
Naming And Rename Hygiene
The repo has already been renamed to icey. Do not introduce new references to the older LibSourcey, Sourcey, or scy project naming for library code, namespaces, include paths, or contributor docs unless you are referring to an external tool or historical changelog entry on purpose.
