From cafdeefa11c972c1dbb20abbc2ccd0b7ebeb6265 Mon Sep 17 00:00:00 2001 From: "Christopher M. Punches" Date: Sat, 15 Aug 2026 20:51:44 -0400 Subject: [PATCH] Describe dpm_module_execute as the entry point, not the whole surface A module's reported version is consumed: a calling module reads it through dpm_module_info_of and decides from it whether to issue a command. Calling dpm_module_execute the module's entire functional surface contradicted that. dpm_module_execute is the only entry through which a module performs work. dpm_module_version and dpm_module_description are what it reports about itself, read at load and served to consumers, and the contract page in the public header now says so. --- docs/DESIGN.md | 2 +- docs/MODULES.md | 2 +- include/dpm/core.h | 18 ++++++++++++++---- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/docs/DESIGN.md b/docs/DESIGN.md index ea6f069..ab9fc5e 100644 --- a/docs/DESIGN.md +++ b/docs/DESIGN.md @@ -103,7 +103,7 @@ Returns a human-readable description of the most recent failure recorded on this A module is one .so in the module directory. It includes ``, links `-ldpm-core`, and exports the following reserved symbols as extern "C". Returned strings are static or module-owned, non-NULL, and valid for the lifetime of the loaded module; the library and consumers never free them. **`int dpm_module_execute(dpm_ctx* ctx, const char* command, int argc, char** argv)`** -The module's command entry point, and its entire functional surface. `ctx` is the host context that dispatched the call — the module reaches every service (`dpm_log`, `dpm_config_get`, `dpm_module_path`, ...) through it, and reaches peer modules through it as well. `command` is the subcommand name (equal to argv[0] when argc > 0); argc/argv are the remaining CLI-style arguments. NULL or empty `command` must behave as the module's help command. Returns 0 on success, nonzero on failure. It must be callable immediately after load with no other setup. +The module's command entry point, and the only entry through which it performs work. `ctx` is the host context that dispatched the call — the module reaches every service (`dpm_log`, `dpm_config_get`, `dpm_module_path`, ...) through it, and reaches peer modules through it as well. `command` is the subcommand name (equal to argv[0] when argc > 0); argc/argv are the remaining CLI-style arguments. NULL or empty `command` must behave as the module's help command. Returns 0 on success, nonzero on failure. It must be callable immediately after load with no other setup. **`const char* dpm_module_version(void)`** Returns the module's own version as an X.Y.Z string. Must be constant for the life of the module. This is the value the library reports to consumers, and the value they judge compatibility against. diff --git a/docs/MODULES.md b/docs/MODULES.md index e3b08d1..0a8735a 100644 --- a/docs/MODULES.md +++ b/docs/MODULES.md @@ -7,7 +7,7 @@ A DPM module is one shared object in the module directory. libdpm-core.so loads A module includes ``, links `-ldpm-core`, and exports the following symbols as extern "C". All returned strings must be non-NULL, static or module-owned, and valid for the lifetime of the loaded module; callers never free them. **`int dpm_module_execute(dpm_ctx* ctx, const char* command, int argc, char** argv)`** -The command entry point, and the module's entire functional surface. `ctx` is the host context that dispatched the call; the module reaches every service (`dpm_log`, `dpm_config_get`, `dpm_module_path`, ...) through it, and reaches peer modules through it as well. `command` is the subcommand name, equal to argv[0] when argc > 0. NULL or empty `command` must behave as the module's help command. Returns 0 on success, nonzero on failure. It must be callable immediately after load with no other setup. +The command entry point, and the only entry through which the module performs work. `ctx` is the host context that dispatched the call; the module reaches every service (`dpm_log`, `dpm_config_get`, `dpm_module_path`, ...) through it, and reaches peer modules through it as well. `command` is the subcommand name, equal to argv[0] when argc > 0. NULL or empty `command` must behave as the module's help command. Returns 0 on success, nonzero on failure. It must be callable immediately after load with no other setup. **`const char* dpm_module_version(void)`** The module's own version as an X.Y.Z string. libdpm-core.so reports this value to consumers, and each consumer decides for itself whether the version suits it. diff --git a/include/dpm/core.h b/include/dpm/core.h index e463bc0..e121427 100644 --- a/include/dpm/core.h +++ b/include/dpm/core.h @@ -351,10 +351,16 @@ DPM_API const char* dpm_last_error(dpm_ctx* ctx); * * @section module_contract_surface The Functional Surface * - * dpm_module_execute is the module's entire functional surface; its - * capabilities are addressed by command string, so a module publishes - * no headers, struct layouts, or symbols to anything that calls it. - * NULL or an empty command behaves as the module's help command. + * dpm_module_execute is the only entry through which a module performs + * work; its capabilities are addressed by command string, so a module + * publishes no headers, struct layouts, or symbols to anything that + * calls it. NULL or an empty command behaves as the module's help + * command. + * + * dpm_module_version and dpm_module_description are what a module + * reports about itself. The library reads both at load and serves them + * to consumers through dpm_module_info_of, where the version is what a + * calling module judges before deciding to issue a command. * * @section module_contract_version Version Compatibility * @@ -364,6 +370,10 @@ DPM_API const char* dpm_last_error(dpm_ctx* ctx); * module is built against the system-installed libdpm-core.so and is * responsible for being correct against it. * + * The same holds toward a peer. A module requires the peer by name, + * reads the version the library reports, and decides whether that + * version suits the commands it intends to issue. + * * @section module_contract_validation Validation * * The library refuses to load any module that does not validate