Community-only audit (2026-09-23)
The edition split has always been written from one direction: Editions and modules documents what Enterprise adds. Nobody had ever checked the reverse - whether a Community server offers something an Enterprise server does not. The owner's rule is that Enterprise must be a strict superset of Community: anything Community has that Enterprise lacks is a defect, unless the owner rules it a deliberate exception.
This page is the result of that check, and the allow-list every future
Community-only name is measured against. TestCommunityOnlyIsExactlyTheAuditsDeliberateList
(hitechcloudpanel/internal/modules/edition_test.go) fails the build if a new
Community-only feature reaches internal/core/licence/features.go without
first being added here - the same way TestTheCompiledSplitMatchesTheCatalogue
fails if the forward split (what Enterprise adds) drifts from
features.json.
Sources checked
configuration/hitechadmin/config/modules.json- is everycommunitymodule also installed on a licensed server?configuration/hitechadmin/config/features.jsonandinternal/core/licence/features.go- thecommunityOnlymap is by definition a list of things Enterprise cannot reach.- The Go and Rust route tables, sidebars and templates in
hitechcloudpanel,hitechcloudadminandhitechcloudcli- any branch that shows or enables something only when the edition is Community. INSTALL.shand the installer it drives - anything set up only when unlicensed.
Webmail/Roundcube/mail-client-shaped findings are out of scope for this round (W1 is building the Roundcube installer, W2 the CE→EE data guarantees, W3 Enterprise webmail parity) and are listed below pointing at their ground, without a verdict.
For the owner to confirm
One deliberate case was already known and is implemented and tested
(internal/core/licence/features.go, TestTheAccountsServicesViewIsCommunityOnly).
The audit found two more that look deliberate for the same kind of reason -
a page that only makes sense before the machine the administrator's panel
runs on is licensed - but neither has been through an owner ruling before.
Left unchanged pending that ruling:
/licence(licence key entry, sidebar link "Activate Enterprise") - Community-only. It is the only place to enter a licence key, because on Community2087does not answer at all - there is no administrator panel to do it from instead. On Enterprise the key already exists (that is what made the server Enterprise), so the page 404s (hitechcloudpanel/internal/modules/licence/licence.go). Looks structural, likeservices, but nobody has ruled on it.- The GitHub project link in the footer and the login page - wrapped in
{{if not .IsEnterprise}}inhitechcloudpanel/internal/web/templates/partials/_footer.htmlandinternal/web/templates/user/_login.html. Cosmetic open-source branding, not a capability - but it is still something Community shows that Enterprise does not, so it belongs on this list rather than being silently assumed fine.
Findings
| Item | Where | Why Community-only | Verdict |
|---|---|---|---|
Account's own services view (/services, feature services) | hitechcloudpanel/internal/core/licence/features.go (communityOnly), internal/modules/registry.go, sidebar | On Community the signed-in account owns the whole server (2087 does not answer), so it may restart the services its sites run on. On Enterprise those services are shared between every account and belong to the administrator's panel (2087). | Deliberate (owner-confirmed; the one case named in this round's brief). Not changed. |
/licence licence-key entry page | internal/modules/licence/licence.go, internal/app/userdata.go (licence_activation), internal/web/sidebar.go | Only place to enter a licence on Community, because 2087 does not exist yet to do it from. 404s on Enterprise. | Proposed deliberate - owner ruling requested (see above). Not changed. |
| GitHub / open-source branding links (footer, login page) | internal/web/templates/partials/_footer.html:39, internal/web/templates/user/_login.html:73 | Community-edition self-promotion; cosmetic, not a feature. | Proposed deliberate - owner ruling requested (see above). Not changed. |
| PHP version install/remove on the account's own panel | Community-only in hitechcloudpanel/internal/modules/php/{install_version,remove_version}.go (phpVersionsManageable) and the Rust twin render_default.rs | PHP versions are server-wide; management moves to the administrator on Enterprise. | Wrong shape, not missing. Enterprise has it at hitechcloudadmin/internal/handlers/php_versions.go (2087), the same move services makes. No fix needed. |
13 modules tagged edition: "community" in modules.json (php, mariadb, redis, valkey, memcached, goaccess, acme, firewall, fail2ban, mail, ftp, clamav, webmail-roundcube) | configuration/hitechadmin/config/modules.json, hitechcloudcli/native/module.rs | Base hosting stack every server needs. | Wrong shape / already a superset, with one defect found underneath it (next row). webmail-roundcube is W1's ground, not evaluated further here. |
hitechcloudcli module install --edition enterprise did not install the 13 Community modules | hitechcloudcli/native/module.rs (the install/uninstall/repair match arm, wanted filter) | The filter matched on exact edition (m.edition == e), so --edition enterprise selected only the 17 modules tagged enterprise; components_for_edition (the fresh-install path) already did this correctly, but the licence-upgrade path did not, contradicting its own doc comment and the design in Editions and modules. A server licensed by any route other than upgrading a running Community install (a licence applied straight after a bare install, or a repair after --purge) would come up without PHP, MariaDB, mail, FTP or any other Community module. | Defect - fixed. install/repair/uninstall now resolve --edition <e> through the same modules_for_edition helper as components_for_edition, so enterprise is a strict superset again. Tests: installing_the_enterprise_edition_also_wants_every_community_module, installing_the_community_edition_wants_only_community_modules (native/module.rs). |
hitechcloudcli admin logs (multitail over the admin's own log files) excluded the API request log on Enterprise | hitechcloudcli/admin.rs (logs(), now log_files()) | The condition was inverted: API_LOG was tailed only when licence_key().is_empty() (Community). That log records the licensed REST API (/settings/api, RequireAPIFeatureEnabled in hitechcloudadmin), which only answers on Enterprise - so Community's copy of the file can never hold a line, and Enterprise, the one edition the log means anything on, was the one this command left out. | Defect - fixed. log_files() now includes API_LOG unconditionally, like every other file it tails. Test: admin_logs_always_includes_the_api_log (admin.rs). |
INSTALL.sh WITH_COMPONENTS (Community vs Enterprise component lists passed to install) | INSTALL.sh:60-116 | Sets the components a fresh install asks for, keyed on whether a licence key was given at install time. | No gap. Every Community component is also in the Enterprise list; the installer's own split is already a superset. The only other licence-key conditionals in the file are informational echoes, not install/config steps. |
enterpriseOnly (43 features) and communityOnly (services, above) in features.go vs features.json | internal/core/licence/features.go | The forward split (what Enterprise adds) was already pinned by TestTheCompiledSplitMatchesTheCatalogue; the reverse split had no equivalent guard. | Guard added. TestCommunityOnlyIsExactlyTheAuditsDeliberateList pins the compiled communityOnly map to deliberateCommunityOnly = []string{"services"} (this document's confirmed entry) and fails if features.json ever grows a community_only marker that isn't wired into the same comparison. |
| Roundcube webmail SSO / feature gate | hitechcloudpanel/internal/modules/emails/webmail.go:108 | Webmail-shaped. | Not evaluated here - belongs to W1 (Roundcube installer), W2 (CE→EE data guarantees) and W3 (Enterprise webmail parity). |
Rules this audit keeps
- Enterprise is a superset of Community: every module, feature and page Community has, Enterprise has too, under its own name or a different one - never simply missing.
- A gap found here is fixed in the same round it is found, in Rust, with a test - not filed for later.
- A Community-only name that is genuinely a design decision is recorded here and left alone; it does not get "fixed" out of existence.
TestCommunityOnlyIsExactlyTheAuditsDeliberateListkeeps this document honest: the compiled split can only ever contain what this page has ruled deliberate.