Do non-publishable EK9 packages need capability declarations?
← Package Capability Security · Ref: Q1275
No — non-publishable packages are entirely exempt from capability enforcement. You can freely use Stdout, File, TCP, EnvVars, or any other gated type without declaring them in a 'capabilities' block.
A package is NON-PUBLISHABLE when any of the four publishable conditions is missing:
- publicAccess is not declared - version is not declared - license is not declared - capabilities block is not present
When any of these is missing, the compiler does not activate capability enforcement for the module. This matches the reality that local scripts, developer experiments, file-organisation wrappers, and pure dependency-management 'defines package' blocks are not entering a supply chain. The developer's own machine, the developer's own risk.
COMMON NON-PUBLISHABLE SHAPES
1. Description only — just naming the package for organisation:
defines package description <- "My local project"
2. File organisation with applyStandardIncludes:
defines package description <- "Collected local utilities" applyStandardIncludes <- true
3. Dependency management without publishing intent:
defines package description <- "Pulls in external libraries for local use" deps <- { "ekopen.math.simple.constants": "2.3.14-0" }
All three compile freely and may use any gated types in their source code. The compiler does not run the capability check because 'publishable' evaluates to false.
THE TRANSITION POINT
The moment you declare publicAccess, version, license, AND a capabilities block, your package opts into enforcement. That is the single moment a module 'enters the supply chain' in EK9's model, and the only moment the compiler starts asking 'is this gated type covered by a declared capability?' Until then, you are writing ordinary code on your own machine and nothing is gated.
WHY THE EXEMPTION EXISTS
Forcing capability declarations on every package — including scripts, experiments, and throwaway builds — would create enormous friction for zero security benefit. The attacks capability security is designed to stop are supply-chain attacks: compromised dependencies that end up in other people's builds. Code that never leaves your machine cannot be a supply chain attack. The exemption respects that reality.
See Q1270 for the four publishable conditions. See Q1276 for pure-computation publishable libraries. See Q1278 for the dev/ test exemption within publishable packages.
Example
defines module qa.packagecapabilities.nonpublishable defines package description <- "Non-publishable local package — capabilities not required" defines function freelyUseStdout() stdout <- Stdout() stdout.println("This module has no publicAccess, no version, no license.") stdout.println("It is not publishable, so capability enforcement is not active.") freelyUseStderr() stderr <- Stderr() stderr.println("Stderr is also freely usable here.")
Other ways to ask this
- Can I use Stdout and File freely in a local project that I'm not publishing?
- When is my package exempt from capability enforcement?
- Does the capability rule apply to scripts and local experiments?
- What happens if my package block has only a description?
Coming from another language?
Python virtualenv: local experiments run arbitrary code; no package-level policy. Node.js local package.json: same. Rust workspaces: local members can use any std APIs. Java local projects: no security manager by default. EK9: non-publishable packages explicitly exempt — capability enforcement activates only at the publishable threshold, which is deliberately opt-in.
Keywords: dependency management, exemption, script, local, publishable, non-publishable, experiment