Skip to content
Impulse SoftwareDOCS
Get modules

ImpulseCore

Module manifest & registration

How each Impulse module declares itself to Core. The manifest is read at activation time; nothing else needs to be configured by hand.

Every Impulse module ships a small manifest named impulse_module.json — at modules/servers/{slug}/impulse_module.json for modules with a server module, or modules/addons/{slug}/impulse_module.json for addon-only modules. Core reads it when the module is activated or upgraded. The file is plain JSON — not PHP — so a syntax error in module code can never prevent Core from reading the module’s identity.

An excerpt from ImpulseDB Postgres’s manifest (values change from release to release):

{
"slug": "impulsepostgres",
"display_name": "Managed PostgreSQL",
"version": "1.10.5",
"core_min_version": "1.61.13",
"service_type": "database",
"license_prefix": "IPGRES-",
"addon_module_slug": "impulsepostgres_addon",
"tables": [
"mod_impulsepostgres_settings",
"mod_impulsepostgres_servers",
"mod_impulsepostgres_plans",
"mod_impulsepostgres_services"
],
"cron_tasks": [
{"name": "provision", "cadence": "2min"},
{"name": "usage", "cadence": "hourly"},
{"name": "alert_detection", "cadence": "hourly"},
{"name": "pg_upgrade", "cadence": "5min"}
],
"hooks_consumed": [],
"security": {
"collector": "ImpulsePostgres\\Security\\Collector",
"actuator": "ImpulsePostgres\\Security\\Actuator"
},
"cve_products": [
"cpe:2.3:a:postgresql:postgresql"
],
"licensing": {
"key_prefixes": {"licensed": "IPGRES-", "dev": "IPGRESDEV-"},
"tier_features": {
"free": [],
"licensed": ["dedicated_provision", "replicas", "backups", "maintenance", "ip_allowlist", "custom_domain"],
"dev": ["dedicated_provision", "replicas", "backups", "maintenance", "ip_allowlist", "custom_domain"]
}
},
"admin_proxy": {
"table": "mod_impulsepostgres_servers",
"health_path": "/health",
"secret_encrypted": true
}
}
Field Purpose
slug Stable internal identifier: lowercase letters, digits and underscores. Used as the table prefix (mod_{slug}_*) and the server module’s directory name. Required.
display_name Human-facing name shown in Core’s Modules tab and status surfaces. Must be unique per install. Required.
version Module version (semver). Core records it as the module’s installed version. Required.
core_min_version Minimum ImpulseCore version this module needs. Core refuses to activate the module if it is older, and holds a newer release of an active module until Core is updated.
service_type What kind of service the module sells: for the current modules, one of storage | database | cache | secrets | auth | search | hosting | compute | notifications (core is reserved for ImpulseCore). Drives grouping and icons in cross-module UI. Required.
addon_module_slug The module’s WHMCS addon directory (for example impulsepostgres_addon). Core looks for the module’s hook, cron, lifecycle and security classes under it.
license_prefix The module’s license-key prefix.
licensing Opts the module into Core-managed licensing: key_prefixes maps each tier to its key prefix, tier_features lists what each tier unlocks, and optional dev_tier_limits caps a developer key’s usage. Keys are pasted in Core’s Modules & Licensing → Licenses tab.
tables Lists the module’s own tables. Informational.
cron_tasks Tasks the module wants Core’s cron runner to dispatch. Each task has a name (matched to a handler class in the module’s lib/Cron/ directory) and a cadence: 1min, 2min, 5min, 15min, hourly, daily or weekly.
hooks_consumed Informational list of Core events the module handles. Core installs hook subscriptions from the handler classes it finds in the module’s lib/Hooks/ directory, not from this list.
security Optional. Class names for the Security & Maintenance Collector and Actuator. Core finds these classes in the module’s lib/Security/ directory, including the per-server variants; the manifest entries are belt-and-braces.
cve_products Optional. NVD CPE 2.3 strings naming upstream products this module manages (e.g. PostgreSQL, RustFS, Meilisearch). Core’s daily NVD-by-CPE feed pulls direct-install CVEs for these products.
admin_proxy Optional. Where the module keeps its servers and which health path Core’s 15-minute admin-proxy health check calls.
Other blocks Optional: email (Email Delivery settings), email_templates (Email Center entries), engines (modules that run more than one engine, chosen per server), upstream (managed upstream products and versions), project (Projects participation).

When you click Activate on a module’s addon entry in WHMCS, the module’s activate hook calls ImpulseCore::registerModule() with the path to its manifest, then ImpulseCore::activateModule(). Core then:

  1. Reads the manifest from the module’s directory.
  2. Validates it: required fields present, slug well formed, version semver, service_type known, every cron task named once with a known cadence, and any optional block well formed. An invalid manifest is refused with a readable error.
  3. Compares core_min_version against Core’s own version. If Core is older, the module is listed as registered but not active, Core refuses activateModule() with “Module ‘…’ requires ImpulseCore >= X, but installed Core is Y. Update ImpulseCore before activating this module.” (shown in WHMCS’s activation message) and records a module.activate.core_min_version_unmet error in the audit log.
  4. Inserts or updates the module’s row in mod_impulsecore_modules (slug, display name, version, status, manifest).
  5. Installs hook subscriptions in mod_impulsecore_hook_subscriptions for the handler classes in the module’s lib/Hooks/.
  6. Inserts or updates the module’s cron_tasks in mod_impulsecore_cron_tasks; a new task is due straight away.
  7. Records the module’s lifecycle handler from lib/Lifecycle/, seeds its default monitoring alert rules, and adds its email templates to the Email Center.

Security Collector and Actuator classes are found in the module’s lib/Security/ directory when the Security pipeline runs, and the daily NVD feed reads cve_products from every active module’s manifest.

The whole flow is idempotent — re-running activate updates the existing rows rather than duplicating them. A module upgrade re-registers its manifest the same way, so new cron tasks and hooks arrive with the release; your own changes, such as a disabled cron task, are kept. Modules & Licensing → Modules lists any module release that is waiting for a newer ImpulseCore.

Modules call into a static facade for everything cross-cutting:

// Audit a state change
ImpulseCore::log('impulseobjects', 'server.provisioned', [
'service_id' => 1234, 'region' => 'us-central-dallas',
], 'info');
// Render the customer Security tab on a service page
echo ImpulseCore::renderClientSecurityTab($serviceId);
// Check what the module's license unlocks (Core-managed licensing)
$canReplicate = \ImpulseCore\License::hasFeature('impulseobjects', 'replication');
// Find the other services in the same project
$siblings = ImpulseCore::getSiblings($serviceId);
// Record a Security event (writes to both audit_log AND security_events)
ImpulseCore::recordSecurityEvent($serviceId, 'patch_succeeded', [
'cve' => 'CVE-2024-XXXXX',
]);
Concern What Core provides
Project membership Logical grouping of related services (a Postgres DB + an object-storage bucket + a search instance) into a single customer-facing project.
Cross-service detection “Connected” badge in the customer client area showing related services across modules.
Hook dispatch Re-dispatches WHMCS hooks under canonical event names; modules subscribe by name and never touch WHMCS hook registration directly.
Cron runner Single Core cron entry dispatches every module’s tasks. Every run is logged per task; missed runs surface in Operations → Cron.
Audit log Cross-module audit trail with module, event, level, service / client / project ids, request id and structured context. Single search surface across all modules.
Licensing Shared XML licensing client. Same caching, grace and domain-detection behaviour for every licensed module.
Lifecycle Suspension and termination grace windows, customer warning emails, and the purge at the end.
Security & Maintenance CVE feeds, scheduled patching, pre-patch snapshots, customer maintenance windows.
Connection-string contributor Unified .env exporter with secret masking.