|
Safe API Framework
Layered API framework for safety-related applications (ERTMS RBC reference targeting CENELEC EN 50128 SIL 4)
|
Status: Draft Date: 2026-08-02 Applies to: repository-wide directory structure
Through ADR-001 to ADR-006 the repository grew a two-tier grouping: common/ (layer-agnostic facilities) and os/ (OAL services), each holding every feature's files together — src/os/sapi_timer.c sat next to sapi_nvm.c, sapi_ipc.c, and five others in the same directory. That grouping reflected an architectural distinction worth keeping conceptually (ADR-001/002 still explain why some things depend on the OS and some don't), but as more features were added, finding "everything about the timer service" meant filtering one file out of a flat directory of seven.
Every feature gets its own directory, mirrored across all three trees:
Features: status, types (header-only, no .c/test), buffer, cast, safestate, string, timer, nvm, memory, task, ipc, log, reboot.
Rather than nesting feature folders one level deeper under common//os/ (e.g. src/common/buffer/), the grouping folder is removed entirely and every feature sits directly under src/, include/safeapi/, tests/ as a sibling of every other feature. The common-vs-OAL distinction that motivated the original grouping is still real and still documented (every ADR still explains which features have an OS dependency and which don't; sapi_buffer/sapi_cast/sapi_safestate/sapi_string still have zero dependency on any OAL feature, per ADR-002 section 4's original rule), it's just no longer encoded as a directory level. One flat namespace of feature folders is simpler to navigate than a two-level one for a project this size, and the conceptual grouping is one grep/ADR-read away when it matters (e.g. auditing "does anything in `common` accidentally depend on `os`" is still a valid and answerable question — see section 2.3).
Superseded by ADR-023 (2026-08-07): the 21 per-feature targets this section describes were later collapsed into 4 grouped static libraries (safeapi_core/oal/channels/appmanager) because the fine-grained linking this section promised was never actually exercised by any real consumer. The directory-per-feature layout described in section 2.1 above is unaffected and remains current.
Each src/<feature>/CMakeLists.txt builds a small static library safeapi_<feature>, aliased safeapi::<feature>. Most features have zero inter-feature dependencies and link nothing but the shared include path; sapi_string is the one exception (it calls sapi_buffer_* and sapi_cast_* functions directly) and links safeapi::buffer and safeapi::cast publicly. This was already implicit in ADR-001 section 3.5's "consumer can link the whole OAL or a single service" goal — this ADR is what actually delivers it, down to individual-feature granularity rather than whole-layer granularity.
This ADR describes the whole-repository layout; there is no single "location" for it beyond the repository root itself.